diff --git a/osu.Desktop.VisualTests/Tests/TestCaseNotificationManager.cs b/osu.Desktop.VisualTests/Tests/TestCaseNotificationOverlay.cs similarity index 91% rename from osu.Desktop.VisualTests/Tests/TestCaseNotificationManager.cs rename to osu.Desktop.VisualTests/Tests/TestCaseNotificationOverlay.cs index 849df1263e..3b9c251670 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseNotificationManager.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseNotificationOverlay.cs @@ -12,17 +12,17 @@ using osu.Framework.Graphics.Containers; namespace osu.Desktop.VisualTests.Tests { - internal class TestCaseNotificationManager : TestCase + internal class TestCaseNotificationOverlay : TestCase { public override string Description => @"I handle notifications"; - private readonly NotificationManager manager; + private readonly NotificationOverlay manager; - public TestCaseNotificationManager() + public TestCaseNotificationOverlay() { progressingNotifications.Clear(); - Content.Add(manager = new NotificationManager + Content.Add(manager = new NotificationOverlay { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs index 61e87a6621..51c78ff442 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs @@ -6,6 +6,7 @@ using osu.Desktop.VisualTests.Platform; using osu.Framework.Testing; using osu.Framework.MathUtils; using osu.Game.Beatmaps; +using osu.Game.Database; using osu.Game.Rulesets; using osu.Game.Screens.Select; using osu.Game.Screens.Select.Filter; @@ -29,6 +30,7 @@ namespace osu.Desktop.VisualTests.Tests var storage = new TestStorage(@"TestCasePlaySongSelect"); var backingDatabase = storage.GetDatabase(@"client"); + backingDatabase.CreateTable(); rulesets = new RulesetStore(backingDatabase); manager = new BeatmapManager(storage, null, backingDatabase, rulesets); diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 4974f0c0d1..1f4fd80ca6 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -198,7 +198,7 @@ - + diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 71ae5a6697..6983c51c7d 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -25,16 +25,16 @@ namespace osu.Desktop.Overlays public class VersionManager : OverlayContainer { private UpdateManager updateManager; - private NotificationManager notificationManager; + private NotificationOverlay notificationOverlay; protected override bool HideOnEscape => false; public override bool HandleInput => false; [BackgroundDependencyLoader] - private void load(NotificationManager notification, OsuColour colours, TextureStore textures, OsuGameBase game) + private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game) { - notificationManager = notification; + notificationOverlay = notification; AutoSizeAxes = Axes.Both; Anchor = Anchor.BottomCentre; @@ -116,7 +116,7 @@ namespace osu.Desktop.Overlays if (notification == null) { notification = new UpdateProgressNotification { State = ProgressNotificationState.Active }; - Schedule(() => notificationManager.Post(notification)); + Schedule(() => notificationOverlay.Post(notification)); } Schedule(() => diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index 4a7336535e..102900ae81 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -17,6 +17,12 @@ namespace osu.Game.Beatmaps public event Action BeatmapSetAdded; public event Action BeatmapSetRemoved; + /// + /// The current version of this store. Used for migrations (see ). + /// The initial version is 1. + /// + protected override int StoreVersion => 1; + public BeatmapStore(SQLiteConnection connection) : base(connection) { @@ -50,13 +56,44 @@ namespace osu.Game.Beatmaps cleanupPendingDeletions(); } + /// + /// Perform migrations between two store versions. + /// + /// The current store version. This will be zero on a fresh database initialisation. + /// The target version which we are migrating to (equal to the current ). + protected override void PerformMigration(int currentVersion, int newVersion) + { + base.PerformMigration(currentVersion, newVersion); + + while (currentVersion++ < newVersion) + { + switch (currentVersion) + { + case 1: + // initialising from a version before we had versioning (or a fresh install). + + // force adding of Protected column (not automatically migrated). + Connection.MigrateTable(); + + // remove all existing beatmaps. + foreach (var b in Connection.GetAllWithChildren(null, true)) + Connection.Delete(b, true); + break; + } + } + } + /// /// Add a to the database. /// /// The beatmap to add. public void Add(BeatmapSetInfo beatmapSet) { - Connection.InsertOrReplaceWithChildren(beatmapSet, true); + Connection.RunInTransaction(() => + { + Connection.InsertOrReplaceWithChildren(beatmapSet, true); + }); + BeatmapSetAdded?.Invoke(beatmapSet); } diff --git a/osu.Game/Database/DatabaseBackedStore.cs b/osu.Game/Database/DatabaseBackedStore.cs index 8366775483..bb61fc1870 100644 --- a/osu.Game/Database/DatabaseBackedStore.cs +++ b/osu.Game/Database/DatabaseBackedStore.cs @@ -17,6 +17,8 @@ namespace osu.Game.Database protected readonly Storage Storage; protected readonly SQLiteConnection Connection; + protected virtual int StoreVersion => 1; + protected DatabaseBackedStore(SQLiteConnection connection, Storage storage = null) { Storage = storage; @@ -31,6 +33,28 @@ namespace osu.Game.Database Logger.Error(e, $@"Failed to initialise the {GetType()}! Trying again with a clean database..."); Prepare(true); } + + checkMigrations(); + } + + private void checkMigrations() + { + var storeName = GetType().Name; + + var reportedVersion = Connection.Table().FirstOrDefault(s => s.StoreName == storeName) ?? new StoreVersion + { + StoreName = storeName, + Version = 0 + }; + + if (reportedVersion.Version != StoreVersion) + PerformMigration(reportedVersion.Version, reportedVersion.Version = StoreVersion); + + Connection.InsertOrReplace(reportedVersion); + } + + protected virtual void PerformMigration(int currentVersion, int newVersion) + { } /// diff --git a/osu.Game/Database/StoreVersion.cs b/osu.Game/Database/StoreVersion.cs new file mode 100644 index 0000000000..00314875a6 --- /dev/null +++ b/osu.Game/Database/StoreVersion.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using SQLite.Net.Attributes; + +namespace osu.Game.Database +{ + public class StoreVersion + { + [PrimaryKey] + public string StoreName { get; set; } + + public int Version { get; set; } + } +} diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index ecbf51f8b9..3c454f2af2 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -68,6 +68,14 @@ namespace osu.Game.Graphics.UserInterface sampleClick = audio.Sample.Get(@"UI/generic-click"); sampleHover = audio.Sample.Get(@"UI/generic-hover"); + + Enabled.ValueChanged += enabled_ValueChanged; + Enabled.TriggerChange(); + } + + private void enabled_ValueChanged(bool enabled) + { + this.FadeColour(enabled ? Color4.White : Color4.Gray, 200, Easing.OutQuint); } protected override bool OnClick(InputState state) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 7e3bb44465..57f5c54a18 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -117,7 +117,7 @@ namespace osu.Game.Online.API if (!authentication.HasValidAccessToken && !authentication.AuthenticateWithLogin(Username, Password)) { //todo: this fails even on network-related issues. we should probably handle those differently. - //NotificationManager.ShowMessage("Login failed!"); + //NotificationOverlay.ShowMessage("Login failed!"); log.Add(@"Login failed!"); Password = null; continue; @@ -254,7 +254,7 @@ namespace osu.Game.Online.API { //OsuGame.Scheduler.Add(delegate { - //NotificationManager.ShowMessage($@"We just went {newState}!", newState == APIState.Online ? Color4.YellowGreen : Color4.OrangeRed, 5000); + //NotificationOverlay.ShowMessage($@"We just went {newState}!", newState == APIState.Online ? Color4.YellowGreen : Color4.OrangeRed, 5000); log.Add($@"We just went {newState}!"); Scheduler.Add(delegate { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4f4c2e2883..fe6d2dbb41 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -37,7 +37,7 @@ namespace osu.Game private MusicController musicController; - private NotificationManager notificationManager; + private NotificationOverlay notificationOverlay; private DialogOverlay dialogOverlay; @@ -132,7 +132,7 @@ namespace osu.Game if (s.Beatmap == null) { - notificationManager.Post(new SimpleNotification + notificationOverlay.Post(new SimpleNotification { Text = @"Tried to load a score for a beatmap we don't have!", Icon = FontAwesome.fa_life_saver, @@ -189,7 +189,7 @@ namespace osu.Game Origin = Anchor.TopRight, }, overlayContent.Add); - LoadComponentAsync(notificationManager = new NotificationManager + LoadComponentAsync(notificationOverlay = new NotificationOverlay { Depth = -3, Anchor = Anchor.TopRight, @@ -205,7 +205,7 @@ namespace osu.Game { if (entry.Level < LogLevel.Important) return; - notificationManager.Post(new SimpleNotification + notificationOverlay.Post(new SimpleNotification { Text = $@"{entry.Level}: {entry.Message}" }); @@ -216,7 +216,7 @@ namespace osu.Game dependencies.Cache(chat); dependencies.Cache(userProfile); dependencies.Cache(musicController); - dependencies.Cache(notificationManager); + dependencies.Cache(notificationOverlay); dependencies.Cache(dialogOverlay); // ensure both overlays aren't presented at the same time diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b507aa2315..0dec4228de 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -18,6 +18,7 @@ using osu.Game.Graphics.Processing; using osu.Game.Online.API; using SQLite.Net; using osu.Framework.Graphics.Performance; +using osu.Game.Database; using osu.Game.IO; using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; @@ -97,6 +98,8 @@ namespace osu.Game SQLiteConnection connection = Host.Storage.GetDatabase(@"client"); + connection.CreateTable(); + dependencies.Cache(RulesetStore = new RulesetStore(connection)); dependencies.Cache(FileStore = new FileStore(connection, Host.Storage)); dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host)); diff --git a/osu.Game/Overlays/NotificationManager.cs b/osu.Game/Overlays/NotificationOverlay.cs similarity index 79% rename from osu.Game/Overlays/NotificationManager.cs rename to osu.Game/Overlays/NotificationOverlay.cs index ad0236ae1f..7eabb592c6 100644 --- a/osu.Game/Overlays/NotificationManager.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays { - public class NotificationManager : OsuFocusedOverlayContainer + public class NotificationOverlay : OsuFocusedOverlayContainer { private const float width = 320; @@ -28,6 +28,8 @@ namespace osu.Game.Overlays Width = width; RelativeSizeAxes = Axes.Y; + AlwaysPresent = true; + Children = new Drawable[] { new Box @@ -72,17 +74,20 @@ namespace osu.Game.Overlays public void Post(Notification notification) { - State = Visibility.Visible; + Schedule(() => + { + State = Visibility.Visible; - ++runningDepth; - notification.Depth = notification.DisplayOnTop ? runningDepth : -runningDepth; + ++runningDepth; + notification.Depth = notification.DisplayOnTop ? runningDepth : -runningDepth; - var hasCompletionTarget = notification as IHasCompletionTarget; - if (hasCompletionTarget != null) - hasCompletionTarget.CompletionTarget = Post; + var hasCompletionTarget = notification as IHasCompletionTarget; + if (hasCompletionTarget != null) + hasCompletionTarget.CompletionTarget = Post; - var ourType = notification.GetType(); - sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType)))?.Add(notification); + var ourType = notification.GetType(); + sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType)))?.Add(notification); + }); } protected override void PopIn() @@ -109,4 +114,4 @@ namespace osu.Game.Overlays this.FadeTo(0, TRANSITION_LENGTH / 2); } } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index 5126f6a2a4..dcadc4bf56 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -19,9 +19,9 @@ namespace osu.Game.Overlays.Toolbar } [BackgroundDependencyLoader] - private void load(NotificationManager notificationManager) + private void load(NotificationOverlay notificationOverlay) { - StateContainer = notificationManager; + StateContainer = notificationOverlay; } } } \ No newline at end of file diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 70093a1407..ea75c140db 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -61,7 +61,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader(true)] - private void load(OsuConfigManager config, NotificationManager notificationManager, OsuColour colours) + private void load(OsuConfigManager config, NotificationOverlay notificationOverlay, OsuColour colours) { showHud = config.GetBindable(OsuSetting.ShowInterface); showHud.ValueChanged += hudVisibility => content.FadeTo(hudVisibility ? 1 : 0, duration); @@ -71,7 +71,7 @@ namespace osu.Game.Screens.Play { hasShownNotificationOnce = true; - notificationManager?.Post(new SimpleNotification + notificationOverlay?.Post(new SimpleNotification { Text = @"The score overlay is currently disabled. You can toggle this by pressing Shift+Tab." }); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f8509314be..fa4665fd7d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -80,6 +80,7 @@ + @@ -249,7 +250,7 @@ - +