1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-05 10:23:20 +08:00
This commit is contained in:
Huo Yaoyuan 2024-12-04 10:23:34 -05:00 committed by GitHub
commit 7a98e191a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 40 additions and 32 deletions

View File

@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
{
public partial class LegacyTaikoScroller : CompositeDrawable
{
public Bindable<JudgementResult> LastResult = new Bindable<JudgementResult>();
public Bindable<JudgementResult?> LastResult = new Bindable<JudgementResult?>();
public LegacyTaikoScroller()
{

View File

@ -37,7 +37,7 @@ namespace osu.Game.Graphics.UserInterface
private partial class ToggleTextContainer : TextContainer
{
private readonly StatefulMenuItem menuItem;
private readonly Bindable<object> state;
private readonly Bindable<object?> state;
private readonly SpriteIcon stateIcon;
public ToggleTextContainer(StatefulMenuItem menuItem)
@ -61,7 +61,7 @@ namespace osu.Game.Graphics.UserInterface
state.BindValueChanged(updateState, true);
}
private void updateState(ValueChangedEvent<object> state)
private void updateState(ValueChangedEvent<object?> state)
{
var icon = menuItem.GetIconForState(state.NewValue);

View File

@ -2,7 +2,9 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Diagnostics;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
@ -16,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface
/// <summary>
/// The current state that should be displayed.
/// </summary>
public readonly Bindable<object> State = new Bindable<object>();
public readonly Bindable<object?> State = new Bindable<object?>();
/// <summary>
/// Creates a new <see cref="StatefulMenuItem"/>.
@ -24,7 +26,7 @@ namespace osu.Game.Graphics.UserInterface
/// <param name="text">The text to display.</param>
/// <param name="changeStateFunc">A function that mutates a state to another state after this <see cref="StatefulMenuItem"/> is pressed.</param>
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
protected StatefulMenuItem(LocalisableString text, Func<object, object> changeStateFunc, MenuItemType type = MenuItemType.Standard)
protected StatefulMenuItem(LocalisableString text, Func<object?, object?> changeStateFunc, MenuItemType type = MenuItemType.Standard)
: this(text, changeStateFunc, type, null)
{
}
@ -36,7 +38,7 @@ namespace osu.Game.Graphics.UserInterface
/// <param name="changeStateFunc">A function that mutates a state to another state after this <see cref="StatefulMenuItem"/> is pressed.</param>
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
/// <param name="action">A delegate to be invoked when this <see cref="StatefulMenuItem"/> is pressed.</param>
protected StatefulMenuItem(LocalisableString text, Func<object, object>? changeStateFunc, MenuItemType type, Action<object>? action)
protected StatefulMenuItem(LocalisableString text, Func<object?, object?>? changeStateFunc, MenuItemType type, Action<object?>? action)
: base(text, type)
{
Action.Value = () =>
@ -51,7 +53,7 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
/// <param name="state">The state to retrieve the relevant icon for.</param>
/// <returns>The icon to be displayed for <paramref name="state"/>.</returns>
public abstract IconUsage? GetIconForState(object state);
public abstract IconUsage? GetIconForState(object? state);
}
public abstract class StatefulMenuItem<T> : StatefulMenuItem
@ -81,20 +83,21 @@ namespace osu.Game.Graphics.UserInterface
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
/// <param name="action">A delegate to be invoked when this <see cref="StatefulMenuItem"/> is pressed.</param>
protected StatefulMenuItem(LocalisableString text, Func<T, T>? changeStateFunc, MenuItemType type, Action<T>? action)
: base(text, o => changeStateFunc?.Invoke((T)o) ?? o, type, o => action?.Invoke((T)o))
: base(text, o => changeStateFunc?.Invoke((T)o.AsNonNull()) ?? o, type, o => action?.Invoke((T)o.AsNonNull()))
{
base.State.BindValueChanged(state =>
{
if (state.NewValue == null)
base.State.Value = default(T);
Debug.Assert(base.State.Value != null);
State.Value = (T)base.State.Value;
}, true);
State.BindValueChanged(state => base.State.Value = state.NewValue);
}
public sealed override IconUsage? GetIconForState(object state) => GetIconForState((T)state);
public sealed override IconUsage? GetIconForState(object? state) => GetIconForState((T)state!);
/// <summary>
/// Retrieves the icon to be displayed for a state.

View File

@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Chat
public void TextBoxKillFocus() => chatTextBox.KillFocus();
[Resolved]
private Bindable<Channel> currentChannel { get; set; } = null!;
private Bindable<Channel?> currentChannel { get; set; } = null!;
private Container chattingTextContainer = null!;
private OsuSpriteText chattingText = null!;
@ -138,7 +138,7 @@ namespace osu.Game.Overlays.Chat
currentChannel.BindValueChanged(change =>
{
Channel newChannel = change.NewValue;
Channel? newChannel = change.NewValue;
switch (newChannel?.Type)
{

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using osu.Framework;
@ -200,11 +201,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
currentDisplay.BindValueChanged(display => Schedule(() =>
{
if (display.NewValue == null)
{
resolutions.Clear();
return;
}
Debug.Assert(display.NewValue != null);
resolutions.ReplaceRange(1, resolutions.Count - 1, display.NewValue.DisplayModes
.Where(m => m.Size.Width >= 800 && m.Size.Height >= 600)

View File

@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit.Components
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
protected readonly IBindable<Track> Track = new Bindable<Track>();
protected readonly IBindable<Track?> Track = new Bindable<Track?>();
public readonly Drawable Background;
private readonly Container content;

View File

@ -66,7 +66,7 @@ namespace osu.Game.Screens.Edit.Setup
syncingColours = true;
comboColours.Colours.Clear();
comboColours.Colours.AddRange(Beatmap.BeatmapSkin?.ComboColours);
comboColours.Colours.AddRange(Beatmap.BeatmapSkin?.ComboColours ?? []);
syncingColours = false;
});

View File

@ -81,9 +81,9 @@ namespace osu.Game.Screens.Edit.Timing
effectPoint.ScrollSpeedBindable.Value = scrollSpeed.NewValue;
}
protected override EffectControlPoint CreatePoint()
protected override EffectControlPoint CreatePointFrom(double time)
{
var reference = Beatmap.ControlPointInfo.EffectPointAt(SelectedGroup.Value.Time);
var reference = Beatmap.ControlPointInfo.EffectPointAt(time);
return new EffectControlPoint
{

View File

@ -21,7 +21,7 @@ namespace osu.Game.Screens.Edit.Timing
private OsuButton button = null!;
[Resolved]
protected Bindable<ControlPointGroup> SelectedGroup { get; private set; } = null!;
protected Bindable<ControlPointGroup?> SelectedGroup { get; private set; } = null!;
[Resolved]
protected EditorBeatmap Beatmap { get; private set; } = null!;

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@ -30,7 +31,7 @@ namespace osu.Game.Screens.Edit.Timing
protected EditorBeatmap Beatmap { get; private set; } = null!;
[Resolved]
protected Bindable<ControlPointGroup> SelectedGroup { get; private set; } = null!;
protected Bindable<ControlPointGroup?> SelectedGroup { get; private set; } = null!;
[Resolved]
protected IEditorChangeHandler? ChangeHandler { get; private set; }
@ -103,12 +104,13 @@ namespace osu.Game.Screens.Edit.Timing
}
if (ControlPoint.Value == null)
SelectedGroup.Value.Add(ControlPoint.Value = CreatePoint());
SelectedGroup.Value.Add(ControlPoint.Value = CreatePointFrom(SelectedGroup.Value.Time));
}
else
{
if (ControlPoint.Value != null)
{
Debug.Assert(SelectedGroup.Value != null);
SelectedGroup.Value.Remove(ControlPoint.Value);
ControlPoint.Value = null;
}
@ -128,6 +130,6 @@ namespace osu.Game.Screens.Edit.Timing
protected abstract void OnControlPointChanged(ValueChangedEvent<T?> point);
protected abstract T CreatePoint();
protected abstract T CreatePointFrom(double time);
}
}

View File

@ -31,7 +31,7 @@ namespace osu.Game.Screens.Edit.Timing
private OsuConfigManager configManager { get; set; } = null!;
[Resolved]
private Bindable<ControlPointGroup> selectedGroup { get; set; } = null!;
private Bindable<ControlPointGroup?> selectedGroup { get; set; } = null!;
private readonly BindableBool isHandlingTapping = new BindableBool();

View File

@ -83,9 +83,9 @@ namespace osu.Game.Screens.Edit.Timing
}
}
protected override TimingControlPoint CreatePoint()
protected override TimingControlPoint CreatePointFrom(double time)
{
var reference = Beatmap.ControlPointInfo.TimingPointAt(SelectedGroup.Value.Time);
var reference = Beatmap.ControlPointInfo.TimingPointAt(time);
return new TimingControlPoint
{

View File

@ -3,6 +3,7 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -38,6 +39,10 @@ namespace osu.Game.Screens.OnlinePlay.Match
{
this.allowEdit = allowEdit;
// Roslyn sees required non-nullable property as nullable in constructor,
// as it can't see the implementation provides a fallback.
Debug.Assert(SelectedItem != null);
base.SelectedItem.BindTo(SelectedItem);
}

View File

@ -68,7 +68,7 @@ namespace osu.Game.Screens.Select.Leaderboards
}
[Resolved]
private IBindable<RulesetInfo> ruleset { get; set; } = null!;
private IBindable<RulesetInfo?> ruleset { get; set; } = null!;
[Resolved]
private IBindable<IReadOnlyList<Mod>> mods { get; set; } = null!;
@ -186,6 +186,7 @@ namespace osu.Game.Screens.Select.Leaderboards
scoreSubscription?.Dispose();
scoreSubscription = null;
Debug.Assert(ruleset.Value != null);
scoreSubscription = realm.RegisterForNotifications(r =>
r.All<ScoreInfo>().Filter($"{nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $0"
+ $" AND {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.Hash)} == {nameof(ScoreInfo.BeatmapHash)}"

View File

@ -135,7 +135,7 @@ namespace osu.Game.Screens.Select
private FooterButtonOptions beatmapOptionsButton = null!;
private readonly Bindable<RulesetInfo> decoupledRuleset = new Bindable<RulesetInfo>();
private readonly Bindable<RulesetInfo?> decoupledRuleset = new Bindable<RulesetInfo?>();
private double audioFeedbackLastPlaybackTime;
@ -426,7 +426,7 @@ namespace osu.Game.Screens.Select
dependencies.CacheAs(this);
dependencies.CacheAs(decoupledRuleset);
dependencies.CacheAs<IBindable<RulesetInfo>>(decoupledRuleset);
dependencies.CacheAs<IBindable<RulesetInfo?>>(decoupledRuleset);
return dependencies;
}
@ -994,7 +994,7 @@ namespace osu.Game.Screens.Select
selectedMods.BindValueChanged(_ =>
{
if (decoupledRuleset.Value.Equals(rulesetNoDebounce))
if (decoupledRuleset.Value?.Equals(rulesetNoDebounce) ?? false)
advancedStats.Mods.Value = selectedMods.Value;
}, true);

View File

@ -49,7 +49,7 @@ namespace osu.Game.Skinning
SpriteName.BindValueChanged(name =>
{
((SpriteComponentLookup)ComponentLookup).LookupName = name.NewValue ?? string.Empty;
((SpriteComponentLookup)ComponentLookup).LookupName = name.NewValue;
if (IsLoaded)
SkinChanged(CurrentSkin);
});