From d73c0ca65949fa2bff7f8fb4602a350ac8048856 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jun 2022 19:38:51 +0900 Subject: [PATCH 1/7] Remove unused methods from `IModelImporter` All the xmldoc is already present in `RealmArchiveModelImporter` so nothing is lost here. --- osu.Game/Database/IModelImporter.cs | 43 +++++++---------------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/osu.Game/Database/IModelImporter.cs b/osu.Game/Database/IModelImporter.cs index 90df13477e..b59636e88d 100644 --- a/osu.Game/Database/IModelImporter.cs +++ b/osu.Game/Database/IModelImporter.cs @@ -1,14 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using osu.Game.IO.Archives; -using osu.Game.Overlays.Notifications; - #nullable enable +using System.Collections.Generic; +using System.Threading.Tasks; +using osu.Game.Overlays.Notifications; + namespace osu.Game.Database { /// @@ -18,35 +16,14 @@ namespace osu.Game.Database public interface IModelImporter : IPostNotifications, IPostImports, ICanAcceptFiles where TModel : class, IHasGuidPrimaryKey { + /// + /// Process multiple import tasks, updating a tracking notification with progress. + /// + /// The notification to update. + /// The import tasks. + /// The imported models. Task>> Import(ProgressNotification notification, params ImportTask[] tasks); - /// - /// Import one from the filesystem and delete the file on success. - /// Note that this bypasses the UI flow and should only be used for special cases or testing. - /// - /// The containing data about the to import. - /// Whether this is a low priority import. - /// An optional cancellation token. - /// The imported model, if successful. - Task?> Import(ImportTask task, bool lowPriority = false, CancellationToken cancellationToken = default); - - /// - /// Silently import an item from an . - /// - /// The archive to be imported. - /// Whether this is a low priority import. - /// An optional cancellation token. - Task?> Import(ArchiveReader archive, bool lowPriority = false, CancellationToken cancellationToken = default); - - /// - /// Silently import an item from a . - /// - /// The model to be imported. - /// An optional archive to use for model population. - /// Whether this is a low priority import. - /// An optional cancellation token. - Live? Import(TModel item, ArchiveReader? archive = null, bool lowPriority = false, CancellationToken cancellationToken = default); - /// /// A user displayable name for the model type associated with this manager. /// From ca0765a9326100a25994df7acee884a913e60170 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jun 2022 19:46:59 +0900 Subject: [PATCH 2/7] Tidy up various delegation implementations --- osu.Game/Scoring/ScoreManager.cs | 50 +++-------------- osu.Game/Skinning/SkinManager.cs | 88 ++++++++---------------------- osu.Game/Stores/BeatmapImporter.cs | 3 - 3 files changed, 32 insertions(+), 109 deletions(-) diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index fbec6ea1fb..e086135296 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -266,57 +266,23 @@ namespace osu.Game.Scoring }); } - public void Delete(List items, bool silent = false) - { - scoreModelManager.Delete(items, silent); - } + public void Delete(List items, bool silent = false) => scoreModelManager.Delete(items, silent); - public void Undelete(List items, bool silent = false) - { - scoreModelManager.Undelete(items, silent); - } + public void Undelete(List items, bool silent = false) => scoreModelManager.Undelete(items, silent); - public void Undelete(ScoreInfo item) - { - scoreModelManager.Undelete(item); - } + public void Undelete(ScoreInfo item) => scoreModelManager.Undelete(item); - public Task Import(params string[] paths) - { - return scoreModelManager.Import(paths); - } + public Task Import(params string[] paths) => scoreModelManager.Import(paths); - public Task Import(params ImportTask[] tasks) - { - return scoreModelManager.Import(tasks); - } + public Task Import(params ImportTask[] tasks) => scoreModelManager.Import(tasks); public IEnumerable HandledExtensions => scoreModelManager.HandledExtensions; - public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) - { - return scoreModelManager.Import(notification, tasks); - } + public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => scoreModelManager.Import(notification, tasks); - public Task> Import(ImportTask task, bool lowPriority = false, CancellationToken cancellationToken = default) - { - return scoreModelManager.Import(task, lowPriority, cancellationToken); - } + public Live Import(ScoreInfo item, ArchiveReader archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) => scoreModelManager.Import(item, archive, lowPriority, cancellationToken); - public Task> Import(ArchiveReader archive, bool lowPriority = false, CancellationToken cancellationToken = default) - { - return scoreModelManager.Import(archive, lowPriority, cancellationToken); - } - - public Live Import(ScoreInfo item, ArchiveReader archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) - { - return scoreModelManager.Import(item, archive, lowPriority, cancellationToken); - } - - public bool IsAvailableLocally(ScoreInfo model) - { - return scoreModelManager.IsAvailableLocally(model); - } + public bool IsAvailableLocally(ScoreInfo model) => scoreModelManager.IsAvailableLocally(model); #endregion diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 5e1902f520..e04bdce5fd 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -268,37 +268,21 @@ namespace osu.Game.Skinning set => skinModelManager.PostImport = value; } - public Task Import(params string[] paths) - { - return skinModelManager.Import(paths); - } + public Task Import(params string[] paths) => skinModelManager.Import(paths); - public Task Import(params ImportTask[] tasks) - { - return skinModelManager.Import(tasks); - } + public Task Import(params ImportTask[] tasks) => skinModelManager.Import(tasks); public IEnumerable HandledExtensions => skinModelManager.HandledExtensions; - public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) - { - return skinModelManager.Import(notification, tasks); - } + public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => skinModelManager.Import(notification, tasks); - public Task> Import(ImportTask task, bool lowPriority = false, CancellationToken cancellationToken = default) - { - return skinModelManager.Import(task, lowPriority, cancellationToken); - } + public Task> Import(ImportTask task, bool lowPriority = false, CancellationToken cancellationToken = default) => skinModelManager.Import(task, lowPriority, cancellationToken); - public Task> Import(ArchiveReader archive, bool lowPriority = false, CancellationToken cancellationToken = default) - { - return skinModelManager.Import(archive, lowPriority, cancellationToken); - } + public Task> Import(ArchiveReader archive, bool lowPriority = false, CancellationToken cancellationToken = default) => + skinModelManager.Import(archive, lowPriority, cancellationToken); - public Live Import(SkinInfo item, ArchiveReader archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) - { - return skinModelManager.Import(item, archive, lowPriority, cancellationToken); - } + public Live Import(SkinInfo item, ArchiveReader archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) => + skinModelManager.Import(item, archive, lowPriority, cancellationToken); #endregion @@ -323,46 +307,22 @@ namespace osu.Game.Skinning }); } + public bool Delete(SkinInfo item) => skinModelManager.Delete(item); + + public void Delete(List items, bool silent = false) => skinModelManager.Delete(items, silent); + + public void Undelete(List items, bool silent = false) => skinModelManager.Undelete(items, silent); + + public void Undelete(SkinInfo item) => skinModelManager.Undelete(item); + + public bool IsAvailableLocally(SkinInfo model) => skinModelManager.IsAvailableLocally(model); + + public void ReplaceFile(SkinInfo model, RealmNamedFileUsage file, Stream contents) => skinModelManager.ReplaceFile(model, file, contents); + + public void DeleteFile(SkinInfo model, RealmNamedFileUsage file) => skinModelManager.DeleteFile(model, file); + + public void AddFile(SkinInfo model, Stream contents, string filename) => skinModelManager.AddFile(model, contents, filename); + #endregion - - public bool Delete(SkinInfo item) - { - return skinModelManager.Delete(item); - } - - public void Delete(List items, bool silent = false) - { - skinModelManager.Delete(items, silent); - } - - public void Undelete(List items, bool silent = false) - { - skinModelManager.Undelete(items, silent); - } - - public void Undelete(SkinInfo item) - { - skinModelManager.Undelete(item); - } - - public bool IsAvailableLocally(SkinInfo model) - { - return skinModelManager.IsAvailableLocally(model); - } - - public void ReplaceFile(SkinInfo model, RealmNamedFileUsage file, Stream contents) - { - skinModelManager.ReplaceFile(model, file, contents); - } - - public void DeleteFile(SkinInfo model, RealmNamedFileUsage file) - { - skinModelManager.DeleteFile(model, file); - } - - public void AddFile(SkinInfo model, Stream contents, string filename) - { - skinModelManager.AddFile(model, contents, filename); - } } } diff --git a/osu.Game/Stores/BeatmapImporter.cs b/osu.Game/Stores/BeatmapImporter.cs index f04a0210ef..3d89dfeca9 100644 --- a/osu.Game/Stores/BeatmapImporter.cs +++ b/osu.Game/Stores/BeatmapImporter.cs @@ -39,9 +39,6 @@ namespace osu.Game.Stores protected override string[] HashableFileTypes => new[] { ".osu" }; - // protected override bool CheckLocalAvailability(RealmBeatmapSet model, System.Linq.IQueryable items) - // => base.CheckLocalAvailability(model, items) || (model.OnlineID > -1)); - private readonly BeatmapOnlineLookupQueue? onlineLookupQueue; protected BeatmapImporter(RealmAccess realm, Storage storage, BeatmapOnlineLookupQueue? onlineLookupQueue = null) From 9f599a5ab4b32cace5f90cc9eb158a4da90c759f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jun 2022 19:52:30 +0900 Subject: [PATCH 3/7] Remove unused `lowPriority` flag from one `Import` method --- .../Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs | 4 ++-- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Scoring/ScoreManager.cs | 2 +- osu.Game/Skinning/SkinManager.cs | 2 +- osu.Game/Stores/RealmArchiveModelImporter.cs | 5 ++--- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs index db988a544d..278acce3e5 100644 --- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs @@ -225,10 +225,10 @@ namespace osu.Game.Tests.Online this.testBeatmapManager = testBeatmapManager; } - public override Live Import(BeatmapSetInfo item, ArchiveReader archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) + public override Live Import(BeatmapSetInfo item, ArchiveReader archive = null, CancellationToken cancellationToken = default) { testBeatmapManager.AllowImport.Task.WaitSafely(); - return (testBeatmapManager.CurrentImport = base.Import(item, archive, lowPriority, cancellationToken)); + return (testBeatmapManager.CurrentImport = base.Import(item, archive, cancellationToken)); } } } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index dba457c81c..1a536a22b1 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -374,7 +374,7 @@ namespace osu.Game.Beatmaps public Live? Import(BeatmapSetInfo item, ArchiveReader? archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) { - return beatmapModelManager.Import(item, archive, lowPriority, cancellationToken); + return beatmapModelManager.Import(item, archive, cancellationToken); } public IEnumerable HandledExtensions => beatmapModelManager.HandledExtensions; diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index e086135296..d42bf1b454 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -280,7 +280,7 @@ namespace osu.Game.Scoring public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => scoreModelManager.Import(notification, tasks); - public Live Import(ScoreInfo item, ArchiveReader archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) => scoreModelManager.Import(item, archive, lowPriority, cancellationToken); + public Live Import(ScoreInfo item, ArchiveReader archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) => scoreModelManager.Import(item, archive, cancellationToken); public bool IsAvailableLocally(ScoreInfo model) => scoreModelManager.IsAvailableLocally(model); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index e04bdce5fd..7ec922987b 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -282,7 +282,7 @@ namespace osu.Game.Skinning skinModelManager.Import(archive, lowPriority, cancellationToken); public Live Import(SkinInfo item, ArchiveReader archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) => - skinModelManager.Import(item, archive, lowPriority, cancellationToken); + skinModelManager.Import(item, archive, cancellationToken); #endregion diff --git a/osu.Game/Stores/RealmArchiveModelImporter.cs b/osu.Game/Stores/RealmArchiveModelImporter.cs index e7477cfffc..1ff42130b1 100644 --- a/osu.Game/Stores/RealmArchiveModelImporter.cs +++ b/osu.Game/Stores/RealmArchiveModelImporter.cs @@ -250,7 +250,7 @@ namespace osu.Game.Stores return null; } - var scheduledImport = Task.Factory.StartNew(() => Import(model, archive, lowPriority, cancellationToken), + var scheduledImport = Task.Factory.StartNew(() => Import(model, archive, cancellationToken), cancellationToken, TaskCreationOptions.HideScheduler, lowPriority ? import_scheduler_low_priority : import_scheduler); @@ -318,9 +318,8 @@ namespace osu.Game.Stores /// /// The model to be imported. /// An optional archive to use for model population. - /// Whether this is a low priority import. /// An optional cancellation token. - public virtual Live? Import(TModel item, ArchiveReader? archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) + public virtual Live? Import(TModel item, ArchiveReader? archive = null, CancellationToken cancellationToken = default) { return Realm.Run(realm => { From 84e526a2d94d7a20fa53c3a84b0bcdda53a4c70f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jun 2022 20:00:08 +0900 Subject: [PATCH 4/7] Move methods around to make more sense --- osu.Game/Stores/RealmArchiveModelImporter.cs | 110 +++++++++---------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/osu.Game/Stores/RealmArchiveModelImporter.cs b/osu.Game/Stores/RealmArchiveModelImporter.cs index 1ff42130b1..4ea2a10288 100644 --- a/osu.Game/Stores/RealmArchiveModelImporter.cs +++ b/osu.Game/Stores/RealmArchiveModelImporter.cs @@ -258,61 +258,6 @@ namespace osu.Game.Stores return await scheduledImport.ConfigureAwait(false); } - /// - /// Any file extensions which should be included in hash creation. - /// Generally should include all file types which determine the file's uniqueness. - /// Large files should be avoided if possible. - /// - /// - /// This is only used by the default hash implementation. If is overridden, it will not be used. - /// - protected abstract string[] HashableFileTypes { get; } - - internal static void LogForModel(TModel? model, string message, Exception? e = null) - { - string trimmedHash; - if (model == null || !model.IsValid || string.IsNullOrEmpty(model.Hash)) - trimmedHash = "?????"; - else - trimmedHash = model.Hash.Substring(0, 5); - - string prefix = $"[{trimmedHash}]"; - - if (e != null) - Logger.Error(e, $"{prefix} {message}", LoggingTarget.Database); - else - Logger.Log($"{prefix} {message}", LoggingTarget.Database); - } - - /// - /// Whether the implementation overrides with a custom implementation. - /// Custom hash implementations must bypass the early exit in the import flow (see usage). - /// - protected virtual bool HasCustomHashFunction => false; - - /// - /// Create a SHA-2 hash from the provided archive based on file content of all files matching . - /// - /// - /// In the case of no matching files, a hash will be generated from the passed archive's . - /// - protected virtual string ComputeHash(TModel item) - { - // for now, concatenate all hashable files in the set to create a unique hash. - MemoryStream hashable = new MemoryStream(); - - foreach (RealmNamedFileUsage file in item.Files.Where(f => HashableFileTypes.Any(ext => f.Filename.EndsWith(ext, StringComparison.OrdinalIgnoreCase))).OrderBy(f => f.Filename)) - { - using (Stream s = Files.Store.GetStream(file.File.GetStoragePath())) - s.CopyTo(hashable); - } - - if (hashable.Length > 0) - return hashable.ComputeSHA2Hash(); - - return item.Hash; - } - /// /// Silently import an item from a . /// @@ -419,6 +364,61 @@ namespace osu.Game.Stores }); } + /// + /// Any file extensions which should be included in hash creation. + /// Generally should include all file types which determine the file's uniqueness. + /// Large files should be avoided if possible. + /// + /// + /// This is only used by the default hash implementation. If is overridden, it will not be used. + /// + protected abstract string[] HashableFileTypes { get; } + + internal static void LogForModel(TModel? model, string message, Exception? e = null) + { + string trimmedHash; + if (model == null || !model.IsValid || string.IsNullOrEmpty(model.Hash)) + trimmedHash = "?????"; + else + trimmedHash = model.Hash.Substring(0, 5); + + string prefix = $"[{trimmedHash}]"; + + if (e != null) + Logger.Error(e, $"{prefix} {message}", LoggingTarget.Database); + else + Logger.Log($"{prefix} {message}", LoggingTarget.Database); + } + + /// + /// Whether the implementation overrides with a custom implementation. + /// Custom hash implementations must bypass the early exit in the import flow (see usage). + /// + protected virtual bool HasCustomHashFunction => false; + + /// + /// Create a SHA-2 hash from the provided archive based on file content of all files matching . + /// + /// + /// In the case of no matching files, a hash will be generated from the passed archive's . + /// + protected virtual string ComputeHash(TModel item) + { + // for now, concatenate all hashable files in the set to create a unique hash. + MemoryStream hashable = new MemoryStream(); + + foreach (RealmNamedFileUsage file in item.Files.Where(f => HashableFileTypes.Any(ext => f.Filename.EndsWith(ext, StringComparison.OrdinalIgnoreCase))).OrderBy(f => f.Filename)) + { + using (Stream s = Files.Store.GetStream(file.File.GetStoragePath())) + s.CopyTo(hashable); + } + + if (hashable.Length > 0) + return hashable.ComputeSHA2Hash(); + + return item.Hash; + } + private string computeHashFast(ArchiveReader reader) { MemoryStream hashable = new MemoryStream(); From e96c5ce70375a9011da05a4e8bc61a01a7ec16f1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jun 2022 20:00:16 +0900 Subject: [PATCH 5/7] Move and correct xmldoc to interfaces --- osu.Game/Database/ICanAcceptFiles.cs | 10 +++++++++- osu.Game/Stores/RealmArchiveModelImporter.cs | 8 -------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game/Database/ICanAcceptFiles.cs b/osu.Game/Database/ICanAcceptFiles.cs index 74fd6fcc36..3cec3b8a8e 100644 --- a/osu.Game/Database/ICanAcceptFiles.cs +++ b/osu.Game/Database/ICanAcceptFiles.cs @@ -12,14 +12,22 @@ namespace osu.Game.Database public interface ICanAcceptFiles { /// - /// Import the specified paths. + /// Import one or more items from filesystem . /// + /// + /// This will be treated as a low priority batch import if more than one path is specified. + /// This will post notifications tracking progress. + /// /// The files which should be imported. Task Import(params string[] paths); /// /// Import the specified files from the given import tasks. /// + /// + /// This will be treated as a low priority batch import if more than one path is specified. + /// This will post notifications tracking progress. + /// /// The import tasks from which the files should be imported. Task Import(params ImportTask[] tasks); diff --git a/osu.Game/Stores/RealmArchiveModelImporter.cs b/osu.Game/Stores/RealmArchiveModelImporter.cs index 4ea2a10288..35ec0c8532 100644 --- a/osu.Game/Stores/RealmArchiveModelImporter.cs +++ b/osu.Game/Stores/RealmArchiveModelImporter.cs @@ -78,14 +78,6 @@ namespace osu.Game.Stores Files = new RealmFileStore(realm, storage); } - /// - /// Import one or more items from filesystem . - /// - /// - /// This will be treated as a low priority import if more than one path is specified; use to always import at standard priority. - /// This will post notifications tracking progress. - /// - /// One or more archive locations on disk. public Task Import(params string[] paths) { var notification = new ProgressNotification { State = ProgressNotificationState.Active }; From 6250caca29a086a4d8861c5b8c1a13e2510af1dd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jun 2022 20:01:11 +0900 Subject: [PATCH 6/7] Remove duplicate implementation of same thing --- osu.Game/Stores/RealmArchiveModelImporter.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Stores/RealmArchiveModelImporter.cs b/osu.Game/Stores/RealmArchiveModelImporter.cs index 35ec0c8532..82b77bfb05 100644 --- a/osu.Game/Stores/RealmArchiveModelImporter.cs +++ b/osu.Game/Stores/RealmArchiveModelImporter.cs @@ -78,14 +78,7 @@ namespace osu.Game.Stores Files = new RealmFileStore(realm, storage); } - public Task Import(params string[] paths) - { - var notification = new ProgressNotification { State = ProgressNotificationState.Active }; - - PostNotification?.Invoke(notification); - - return Import(notification, paths.Select(p => new ImportTask(p)).ToArray()); - } + public Task Import(params string[] paths) => Import(paths.Select(p => new ImportTask(p)).ToArray()); public Task Import(params ImportTask[] tasks) { From 94ba71aa1323d27ccf97949b914ca15e9b61fd85 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jun 2022 20:21:28 +0900 Subject: [PATCH 7/7] Remove one more usage of `lowPriority` --- osu.Game/Beatmaps/BeatmapManager.cs | 30 ++++++----------------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 1a536a22b1..51f4d23bb4 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -347,35 +347,17 @@ namespace osu.Game.Beatmaps #region Implementation of ICanAcceptFiles - public Task Import(params string[] paths) - { - return beatmapModelManager.Import(paths); - } + public Task Import(params string[] paths) => beatmapModelManager.Import(paths); - public Task Import(params ImportTask[] tasks) - { - return beatmapModelManager.Import(tasks); - } + public Task Import(params ImportTask[] tasks) => beatmapModelManager.Import(tasks); - public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) - { - return beatmapModelManager.Import(notification, tasks); - } + public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => beatmapModelManager.Import(notification, tasks); - public Task?> Import(ImportTask task, bool lowPriority = false, CancellationToken cancellationToken = default) - { - return beatmapModelManager.Import(task, lowPriority, cancellationToken); - } + public Task?> Import(ImportTask task, bool lowPriority = false, CancellationToken cancellationToken = default) => beatmapModelManager.Import(task, lowPriority, cancellationToken); - public Task?> Import(ArchiveReader archive, bool lowPriority = false, CancellationToken cancellationToken = default) - { - return beatmapModelManager.Import(archive, lowPriority, cancellationToken); - } + public Task?> Import(ArchiveReader archive, bool lowPriority = false, CancellationToken cancellationToken = default) => beatmapModelManager.Import(archive, lowPriority, cancellationToken); - public Live? Import(BeatmapSetInfo item, ArchiveReader? archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) - { - return beatmapModelManager.Import(item, archive, cancellationToken); - } + public Live? Import(BeatmapSetInfo item, ArchiveReader? archive = null, CancellationToken cancellationToken = default) => beatmapModelManager.Import(item, archive, cancellationToken); public IEnumerable HandledExtensions => beatmapModelManager.HandledExtensions;