Skip to content

Commit

Permalink
Merge pull request #62 from Piotrekol/startupScreen
Browse files Browse the repository at this point in the history
  • Loading branch information
Piotrekol authored Jun 7, 2022
2 parents a84c211 + c973b84 commit 5f0955a
Show file tree
Hide file tree
Showing 38 changed files with 1,141 additions and 152 deletions.
2 changes: 1 addition & 1 deletion App/App.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net472</TargetFramework>
<TargetFramework>net48</TargetFramework>
<AssemblyTitle>osu! Collection Manager</AssemblyTitle>
<Product>Gui</Product>
<Copyright>Copyright © 2017-present Piotrekol</Copyright>
Expand Down
64 changes: 15 additions & 49 deletions App/Initalizer.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using App.Interfaces;
using App.Misc;
using App.Models;
using App.Models.Forms;
using App.Presenters.Controls;
using App.Presenters.Forms;
using App.Properties;
using CollectionManager.DataTypes;
using CollectionManager.Modules.CollectionsManager;
using CollectionManager.Modules.FileIO;
using CollectionManagerExtensionsDll.Modules.API.osustats;
using CollectionManagerExtensionsDll.Utils;
using Common;
using GuiComponents.Interfaces;

namespace App
Expand All @@ -27,51 +26,14 @@ public class Initalizer : ApplicationContext
public static CollectionEditor CollectionEditor { get; private set; }
private IUserDialogs UserDialogs { get; set; }// = new GuiComponents.UserDialogs();
public static OsuStatsApi WebCollectionProvider = new OsuStatsApi("", OsuFileIo.LoadedMaps);
public void Run(string[] args)
public static StartupPresenter StartupPresenter;

public async Task Run(string[] args)
{
//IUserDialogs can be implemented in WinForm or WPF or Gtk or Console or...?
UserDialogs = GuiComponentsProvider.Instance.GetClassImplementing<IUserDialogs>();

if (Settings.Default.DontAskAboutOsuDirectory)
OsuDirectory = OsuFileIo.OsuPathResolver.GetOsuDir(_ => false, _ => Settings.Default.OsuDirectory);
else
OsuDirectory = OsuFileIo.OsuPathResolver.GetOsuDir(dir =>
{
var result = UserDialogs.YesNoMessageBox($"Detected osu! in \"{dir}\"{Environment.NewLine}Is that correct?", "osu! directory", MessageBoxType.Question,
"Don't ask me again");
Settings.Default.DontAskAboutOsuDirectory = result.doNotAskAgain;
Settings.Default.Save();
return result.Result;
}, UserDialogs.SelectDirectory);

if (string.IsNullOrEmpty(OsuDirectory) && UserDialogs.YesNoMessageBox(
"osu! could not be found. Do you want to continue regardless?" + Environment.NewLine +
"This will cause all .db collections to show only as beatmap hashes.", "osu! location",
MessageBoxType.Question) == false)
{
Quit();
}

if (!string.IsNullOrEmpty(OsuDirectory))
{
Settings.Default.OsuDirectory = OsuDirectory;
Settings.Default.Save();
//Load osu database and setting files
var osuDbFile = Path.Combine(OsuDirectory, @"osu!.db");
var osuScoresFile = Path.Combine(OsuDirectory, @"scores.db");
OsuFileIo.OsuDatabase.Load(osuDbFile);
OsuFileIo.OsuSettings.Load(OsuDirectory);
try
{
OsuFileIo.ScoresLoader.ReadDb(osuScoresFile);
}
catch (Exception e)
{
UserDialogs.OkMessageBox("Warning", "osu! scores database could not be loaded. Score related searches will not work in this session." + Environment.NewLine + Environment.NewLine + e);
}

BeatmapUtils.OsuSongsDirectory = OsuFileIo.OsuSettings.CustomBeatmapDirectoryLocation;
}

//Init "main" classes
CollectionsManager = new CollectionsManagerWithCounts(LoadedBeatmaps);
Expand All @@ -89,6 +51,11 @@ public void Run(string[] args)
//set initial text info and update events
SetTextData(infoTextModel);

var loginForm = GuiComponentsProvider.Instance.GetClassImplementing<ILoginFormView>();
var guiActionsHandler = new GuiActionsHandler(OsuFileIo, CollectionsManager, UserDialogs, mainForm, mainPresenter, loginForm);

if (!string.IsNullOrWhiteSpace(Settings.Default.Osustats_apiKey))
guiActionsHandler.SidePanelActionsHandler.OsustatsLogin(null, Settings.Default.Osustats_apiKey);

if (args.Length > 0)
{
Expand All @@ -98,13 +65,12 @@ public void Run(string[] args)
}
}

var loginForm = GuiComponentsProvider.Instance.GetClassImplementing<ILoginFormView>();
var guiActionsHandler = new GuiActionsHandler(OsuFileIo, CollectionsManager, UserDialogs, mainForm, mainPresenter, loginForm);

if (!string.IsNullOrWhiteSpace(Settings.Default.Osustats_apiKey))
guiActionsHandler.SidePanelActionsHandler.OsustatsLogin(null, Settings.Default.Osustats_apiKey);
StartupPresenter = new StartupPresenter(GuiComponentsProvider.Instance.GetClassImplementing<IStartupForm>(), guiActionsHandler.SidePanelActionsHandler, UserDialogs, CollectionsManager);
await StartupPresenter.Run();


mainForm.ShowAndBlock();

Quit();
}

Expand All @@ -125,7 +91,7 @@ private void SetTextData(IInfoTextModel model)
}


private static void Quit()
public static void Quit()
{
Settings.Default.Save();

Expand Down
12 changes: 12 additions & 0 deletions App/Models/StartupSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Common;

namespace App.Models
{
public class StartupSettings
{
public StartupDatabaseAction StartupDatabaseAction { get; set; }
public StartupCollectionAction StartupCollectionAction { get; set; }
public bool AutoLoadMode { get; set; }
public string OsuLocation { get; set; }
}
}
200 changes: 200 additions & 0 deletions App/Presenters/Controls/StartupPresenter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using App.Models;
using App.Properties;
using CollectionManager.Modules.CollectionsManager;
using CollectionManagerExtensionsDll.Utils;
using Common;
using GuiComponents.Interfaces;
using Newtonsoft.Json;

namespace App.Presenters.Controls
{
public class StartupPresenter
{
private readonly IStartupForm _form;
private readonly IStartupView _view;
private readonly SidePanelActionsHandler _sidePanelActionsHandler;
private readonly IUserDialogs _userDialogs;
private readonly CollectionsManagerWithCounts _collectionsManager;
private StartupSettings _startupSettings;
private CancellationTokenSource _cancellationTokenSource;
private Progress<string> _databaseLoadProgressReporter;
private Task _databaseLoadTask;
private bool _formClosedManually;

public StartupPresenter(IStartupForm view, SidePanelActionsHandler sidePanelActionsHandler, IUserDialogs userDialogs, CollectionsManagerWithCounts collectionsManager)
{
_form = view;
_view = view.StartupView;
_sidePanelActionsHandler = sidePanelActionsHandler;
_userDialogs = userDialogs;
_collectionsManager = collectionsManager;
_startupSettings = JsonConvert.DeserializeObject<StartupSettings>(Settings.Default.StartupSettings);
_cancellationTokenSource = new CancellationTokenSource();
_databaseLoadProgressReporter = new Progress<string>(report =>
{
if (string.IsNullOrEmpty(Initalizer.OsuDirectory))
_view.LoadDatabaseStatusText = report;
else
_view.LoadDatabaseStatusText = $"osu! location: \"{Initalizer.OsuDirectory}\"{Environment.NewLine}{report}";
});

_view.UseSelectedOptionsOnStartup = _startupSettings.AutoLoadMode;
_form.Closing += _view_Closing;
_view.StartupCollectionOperation += _view_StartupCollectionOperation;
_view.StartupDatabaseOperation += _view_StartupDatabaseOperation;
}

public async Task Run()
{
if (_startupSettings.AutoLoadMode && _startupSettings.StartupDatabaseAction == StartupDatabaseAction.Unload)
{
DoCollectionAction();
return;
}

var loadedCollectionFromFile = _collectionsManager.CollectionsCount != 0;
Application.UseWaitCursor = loadedCollectionFromFile || _startupSettings.AutoLoadMode;
_view.UseSelectedOptionsOnStartupEnabled = !loadedCollectionFromFile;
_view.CollectionButtonsEnabled = !(loadedCollectionFromFile || _startupSettings.AutoLoadMode);
_view.DatabaseButtonsEnabled = true;
_view.CollectionStatusText = loadedCollectionFromFile
? $"Going to load {_collectionsManager.CollectionsCount} collections with {_collectionsManager.BeatmapsInCollectionsCount} beatmaps"
: string.Empty;

_databaseLoadTask = Task.Run(() =>
{
LoadDatabase(_cancellationTokenSource.Token);
Application.UseWaitCursor = false;
_view.CollectionButtonsEnabled = true;
});
if (_startupSettings.AutoLoadMode)
_form.Show();
else
_form.ShowAndBlock();

await _databaseLoadTask;
_startupSettings.AutoLoadMode = _view.UseSelectedOptionsOnStartup;
if (!loadedCollectionFromFile)
SaveSettings();

DoCollectionAction();
CloseForm();
}

private void DoCollectionAction()
{
switch (_startupSettings.StartupCollectionAction)
{
case StartupCollectionAction.None:
break;
case StartupCollectionAction.LoadCollectionFromFile:
_sidePanelActionsHandler.LoadCollectionFile();
break;
case StartupCollectionAction.LoadOsuCollection:
_sidePanelActionsHandler.LoadOsuCollection();
break;
}
}

private async void _view_StartupDatabaseOperation(object sender, StartupDatabaseAction args)
{
_startupSettings.StartupDatabaseAction = args;
_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();
_cancellationTokenSource = new CancellationTokenSource();
await _databaseLoadTask;
switch (args)
{
case StartupDatabaseAction.Unload:
Initalizer.OsuFileIo.OsuDatabase.LoadedMaps.UnloadBeatmaps();
Initalizer.OsuFileIo.ScoresDatabase.Clear();
Initalizer.OsuDirectory = null;
_view.LoadOsuCollectionButtonEnabled = false;
GC.Collect();
((IProgress<string>)_databaseLoadProgressReporter).Report("osu! database unloaded");
break;
case StartupDatabaseAction.LoadFromDifferentLocation:
var osuDirectory = Initalizer.OsuFileIo.OsuPathResolver.GetManualOsuDir(_userDialogs.SelectDirectory);
if (!string.IsNullOrEmpty(osuDirectory))
{
_view.LoadOsuCollectionButtonEnabled = true;
_startupSettings.OsuLocation = osuDirectory;
_databaseLoadTask = Task.Run(() => LoadDatabase(_cancellationTokenSource.Token));
}

break;
case StartupDatabaseAction.None:
break;
}
}

private async void _view_StartupCollectionOperation(object sender, StartupCollectionAction args)
{
_startupSettings.StartupCollectionAction = args;
_view.CollectionButtonsEnabled = _view.DatabaseButtonsEnabled = false;
Application.UseWaitCursor = true;
await _databaseLoadTask;
Application.UseWaitCursor = false;
CloseForm();
}

private void CloseForm()
{
_formClosedManually = true;
_form.Close();
}

private void _view_Closing(object sender, EventArgs eventArgs)
{
if (eventArgs is not FormClosingEventArgs formEventArgs || formEventArgs.CloseReason != CloseReason.UserClosing || _formClosedManually)
return;

_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();
Initalizer.Quit();
}

private void LoadDatabase(CancellationToken cancellationToken)
{
var osuFileIo = Initalizer.OsuFileIo;
var osuDirectory = Initalizer.OsuDirectory = string.IsNullOrEmpty(_startupSettings.OsuLocation)
? osuFileIo.OsuPathResolver.GetOsuDir()
: _startupSettings.OsuLocation;

if (string.IsNullOrEmpty(osuDirectory) || !Directory.Exists(osuDirectory))
{
_view.LoadDatabaseStatusText = "osu! could not be found. Select osu! location manually";
return;
}

osuFileIo.OsuDatabase.LoadedMaps.UnloadBeatmaps();
osuFileIo.ScoresDatabase.Clear();
osuFileIo.OsuDatabase.Load(Path.Combine(osuDirectory, @"osu!.db"), _databaseLoadProgressReporter, cancellationToken);
osuFileIo.OsuSettings.Load(osuDirectory);
try
{
osuFileIo.ScoresLoader.ReadDb(Path.Combine(osuDirectory, @"scores.db"), cancellationToken);
_view.LoadDatabaseStatusText += $"{Environment.NewLine}Loaded {osuFileIo.ScoresDatabase.Scores.Count} scores";
}
catch (Exception)
{
_view.LoadDatabaseStatusText += $"{Environment.NewLine}Could not load scores";
}

_view.LoadOsuCollectionButtonEnabled = true;
BeatmapUtils.OsuSongsDirectory = Initalizer.OsuFileIo.OsuSettings.CustomBeatmapDirectoryLocation;
}

private void SaveSettings()
{

Settings.Default.StartupSettings = JsonConvert.SerializeObject(_startupSettings);
Settings.Default.Save();
}
}
}
8 changes: 6 additions & 2 deletions App/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ static int Main(string[] args)
if (exArgs.ExceptionObject is Exception exception)
HandleException(exception);
};
Application.ThreadException += (_, exArgs) => HandleException(exArgs.Exception);
TaskScheduler.UnobservedTaskException += (_, exArgs) => HandleException(exArgs.Exception);
Application.ThreadException += (_, exArgs)
=>
HandleException(exArgs.Exception);
TaskScheduler.UnobservedTaskException += (_, exArgs)
=>
HandleException(exArgs.Exception);

if (args.Length > 0 && !File.Exists(args[0]))
{
Expand Down
Loading

0 comments on commit 5f0955a

Please sign in to comment.