diff --git a/osu.Game/Beatmaps/Drawables/DifficultySpectrumDisplay.cs b/osu.Game/Beatmaps/Drawables/DifficultySpectrumDisplay.cs index 1feaa88350..f4501f0633 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultySpectrumDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultySpectrumDisplay.cs @@ -117,7 +117,7 @@ namespace osu.Game.Beatmaps.Drawables Spacing = new Vector2(1, 0); Direction = FillDirection.Horizontal; - var icon = rulesets.GetRuleset(rulesetId)?.CreateInstance()?.CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }; + var icon = rulesets.GetRuleset(rulesetId)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }; Add(icon.With(i => { i.Size = new Vector2(14); diff --git a/osu.Game/Models/RealmRuleset.cs b/osu.Game/Models/RealmRuleset.cs index 5d70324713..5c18a10527 100644 --- a/osu.Game/Models/RealmRuleset.cs +++ b/osu.Game/Models/RealmRuleset.cs @@ -60,5 +60,27 @@ namespace osu.Game.Models InstantiationInfo = InstantiationInfo, Available = Available }; + + public Ruleset CreateInstance() + { + if (!Available) + throw new RulesetLoadException(@"Ruleset not available"); + + var type = Type.GetType(InstantiationInfo); + + if (type == null) + throw new RulesetLoadException(@"Type lookup failure"); + + var ruleset = Activator.CreateInstance(type) as Ruleset; + + if (ruleset == null) + throw new RulesetLoadException(@"Instantiation failure"); + + // overwrite the pre-populated RulesetInfo with a potentially database attached copy. + // TODO: figure if we still want/need this after switching to realm. + // ruleset.RulesetInfo = this; + + return ruleset; + } } } diff --git a/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs b/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs index 48cbe1b59e..b5d26d4887 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input { public class RulesetBindingsSection : SettingsSection { - public override Drawable CreateIcon() => ruleset?.CreateInstance()?.CreateIcon() ?? new SpriteIcon + public override Drawable CreateIcon() => ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = OsuIcon.Hot }; diff --git a/osu.Game/Rulesets/IRulesetInfo.cs b/osu.Game/Rulesets/IRulesetInfo.cs index c3bc6c1995..4e529a73fb 100644 --- a/osu.Game/Rulesets/IRulesetInfo.cs +++ b/osu.Game/Rulesets/IRulesetInfo.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Database; #nullable enable @@ -28,20 +27,6 @@ namespace osu.Game.Rulesets /// string InstantiationInfo { get; } - Ruleset? CreateInstance() - { - var type = Type.GetType(InstantiationInfo); - - if (type == null) - return null; - - var ruleset = Activator.CreateInstance(type) as Ruleset; - - // overwrite the pre-populated RulesetInfo with a potentially database attached copy. - // TODO: figure if we still want/need this after switching to realm. - // ruleset.RulesetInfo = this; - - return ruleset; - } + Ruleset CreateInstance(); } } diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index ccb614fe91..77be39650f 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Testing; namespace osu.Game.Rulesets @@ -26,9 +25,18 @@ namespace osu.Game.Rulesets // TODO: this should probably be moved to RulesetStore. public Ruleset CreateInstance() { - if (!Available) return null; + if (!Available) + throw new RulesetLoadException(@"Ruleset not available"); - var ruleset = (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo).AsNonNull()); + var type = Type.GetType(InstantiationInfo); + + if (type == null) + throw new RulesetLoadException(@"Type lookup failure"); + + var ruleset = Activator.CreateInstance(type) as Ruleset; + + if (ruleset == null) + throw new RulesetLoadException(@"Instantiation failure"); // overwrite the pre-populated RulesetInfo with a potentially database attached copy. ruleset.RulesetInfo = this; diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index 04767f1786..8d726f7752 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Edit.Setup new DesignSection(), }; - var rulesetSpecificSection = beatmap.BeatmapInfo.Ruleset?.CreateInstance()?.CreateEditorSetupSection(); + var rulesetSpecificSection = beatmap.BeatmapInfo.Ruleset?.CreateInstance().CreateEditorSetupSection(); if (rulesetSpecificSection != null) sectionsEnumerable.Add(rulesetSpecificSection); diff --git a/osu.Game/Screens/Edit/Verify/IssueList.cs b/osu.Game/Screens/Edit/Verify/IssueList.cs index 0b1f988447..fd238feeac 100644 --- a/osu.Game/Screens/Edit/Verify/IssueList.cs +++ b/osu.Game/Screens/Edit/Verify/IssueList.cs @@ -43,7 +43,7 @@ namespace osu.Game.Screens.Edit.Verify private void load(OverlayColourProvider colours) { generalVerifier = new BeatmapVerifier(); - rulesetVerifier = beatmap.BeatmapInfo.Ruleset?.CreateInstance()?.CreateBeatmapVerifier(); + rulesetVerifier = beatmap.BeatmapInfo.Ruleset?.CreateInstance().CreateBeatmapVerifier(); context = new BeatmapVerifierContext(beatmap, workingBeatmap.Value, verify.InterpretedDifficulty.Value); verify.InterpretedDifficulty.BindValueChanged(difficulty => context.InterpretedDifficulty = difficulty.NewValue); diff --git a/osu.Game/Stores/BeatmapImporter.cs b/osu.Game/Stores/BeatmapImporter.cs index 32f0cd3d7a..8ab6941885 100644 --- a/osu.Game/Stores/BeatmapImporter.cs +++ b/osu.Game/Stores/BeatmapImporter.cs @@ -282,9 +282,6 @@ namespace osu.Game.Stores { var rulesetInstance = ((IRulesetInfo)beatmap.Ruleset).CreateInstance(); - if (rulesetInstance == null) - return; - decoded.BeatmapInfo.Ruleset = rulesetInstance.RulesetInfo; // TODO: this should be done in a better place once we actually need to dynamically update it.