Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes for nullability of bindables #23680

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down
4 changes: 2 additions & 2 deletions osu.Game/Graphics/UserInterface/DrawableStatefulMenuItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protected override bool OnMouseDown(MouseDownEvent e)
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)
Expand All @@ -61,7 +61,7 @@ protected override void LoadComplete()
state.BindValueChanged(updateState, true);
}

private void updateState(ValueChangedEvent<object> state)
private void updateState(ValueChangedEvent<object?> state)
{
var icon = menuItem.GetIconForState(state.NewValue);

Expand Down
15 changes: 9 additions & 6 deletions osu.Game/Graphics/UserInterface/StatefulMenuItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -16,15 +18,15 @@ public abstract class StatefulMenuItem : OsuMenuItem
/// <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"/>.
/// </summary>
/// <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)
{
}
Expand All @@ -36,7 +38,7 @@ protected StatefulMenuItem(LocalisableString text, Func<object, object> changeSt
/// <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 = () =>
Expand All @@ -51,7 +53,7 @@ protected StatefulMenuItem(LocalisableString text, Func<object, object>? changeS
/// </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
Expand Down Expand Up @@ -81,20 +83,21 @@ protected StatefulMenuItem(LocalisableString text, Func<T, T>? changeStateFunc,
/// <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.
Expand Down
4 changes: 2 additions & 2 deletions osu.Game/Overlays/Chat/ChatTextBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public partial class ChatTextBar : Container
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!;
Expand Down Expand Up @@ -138,7 +138,7 @@ protected override void LoadComplete()

currentChannel.BindValueChanged(change =>
{
Channel newChannel = change.NewValue;
Channel? newChannel = change.NewValue;

switch (newChannel?.Type)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using osu.Framework;
Expand Down Expand Up @@ -200,11 +201,7 @@

currentDisplay.BindValueChanged(display => Schedule(() =>
{
if (display.NewValue == null)
{
resolutions.Clear();
return;
}
Debug.Assert(display.NewValue != null);

Check failure on line 204 in osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs

View workflow job for this annotation

GitHub Actions / Results

osu.Game.Tests.Visual.Navigation.TestSceneChangeAndUseGameplayBindings ► TestGameplayKeyBindings

Failed test found in: TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-SingleThread.trx Error: System.AggregateException : One or more errors occurred. (: ) ----> NUnit.Framework.AssertionException : :
Raw output
System.AggregateException : One or more errors occurred. (: )
  ----> NUnit.Framework.AssertionException : : 
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at osu.Framework.Extensions.TaskExtensions.WaitSafely(Task task)
   at osu.Framework.Testing.TestScene.UseTestSceneRunnerAttribute.AfterTest(ITest test)
   at NUnit.Framework.Internal.Commands.TestActionCommand.<>c__DisplayClass0_0.<.ctor>b__1(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__1()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
--AssertionException
   at osu.Framework.Logging.ThrowingTraceListener.Fail(String message1, String message2)
   at System.Diagnostics.TraceInternal.Fail(String message, String detailMessage)
   at System.Diagnostics.Debug.Fail(String message, String detailMessage)
   at osu.Game.Overlays.Settings.Sections.Graphics.LayoutSettings.<>c__DisplayClass30_0.<LoadComplete>b__5() in /home/runner/work/osu/osu/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs:line 204
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Graphics.Drawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Platform.GameHost.UpdateFrame()
   at osu.Framework.Threading.GameThread.processFrame()
--- End of stack trace from previous location ---
   at osu.Framework.Platform.GameHost.<>c__DisplayClass141_0.<abortExecutionFromException>b__0()
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Threading.GameThread.processFrame()
   at osu.Framework.Platform.ThreadRunner.RunMainLoop()
   at osu.Framework.Platform.GameHost.windowUpdate()
   at osu.Framework.Platform.GameHost.Run(Game game)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

Check failure on line 204 in osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs

View workflow job for this annotation

GitHub Actions / Results

osu.Game.Tests.Visual.Navigation.TestSceneScreenNavigation ► TestRetryCountIncrements

Failed test found in: TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx Error: System.AggregateException : One or more errors occurred. (: ) ----> NUnit.Framework.AssertionException : :
Raw output
System.AggregateException : One or more errors occurred. (: )
  ----> NUnit.Framework.AssertionException : : 
   at osu.Framework.Testing.TestScene.UseTestSceneRunnerAttribute.AfterTest(ITest test)
   at NUnit.Framework.Internal.Commands.TestActionCommand.<>c__DisplayClass0_0.<.ctor>b__1(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__1()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
--AssertionException
   at osu.Framework.Logging.ThrowingTraceListener.Fail(String message1, String message2)
   at System.Diagnostics.TraceInternal.Fail(String message, String detailMessage)
   at System.Diagnostics.Debug.Fail(String message, String detailMessage)
   at osu.Game.Overlays.Settings.Sections.Graphics.LayoutSettings.<>c__DisplayClass30_0.<LoadComplete>b__5() in /home/runner/work/osu/osu/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs:line 204
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Graphics.Drawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Platform.GameHost.UpdateFrame()
   at osu.Framework.Threading.GameThread.processFrame()
--- End of stack trace from previous location ---
   at osu.Framework.Platform.GameHost.<>c__DisplayClass141_0.<abortExecutionFromException>b__0()
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Threading.GameThread.processFrame()
   at osu.Framework.Platform.ThreadRunner.RunMainLoop()
   at osu.Framework.Platform.GameHost.windowUpdate()
   at osu.Framework.Platform.GameHost.Run(Game game)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

Check failure on line 204 in osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs

View workflow job for this annotation

GitHub Actions / Results

osu.Game.Tests.Visual.Settings.TestSceneSettingsPanel ► TestFilterAfterLoad

Failed test found in: TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx Error: System.AggregateException : One or more errors occurred. (: ) ----> NUnit.Framework.AssertionException : :
Raw output
System.AggregateException : One or more errors occurred. (: )
  ----> NUnit.Framework.AssertionException : : 
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at osu.Framework.Extensions.TaskExtensions.WaitSafely(Task task)
   at osu.Framework.Testing.TestScene.UseTestSceneRunnerAttribute.AfterTest(ITest test)
   at NUnit.Framework.Internal.Commands.TestActionCommand.<>c__DisplayClass0_0.<.ctor>b__1(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__1()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
--AssertionException
   at osu.Framework.Logging.ThrowingTraceListener.Fail(String message1, String message2)
   at System.Diagnostics.TraceInternal.Fail(String message, String detailMessage)
   at System.Diagnostics.Debug.Fail(String message, String detailMessage)
   at osu.Game.Overlays.Settings.Sections.Graphics.LayoutSettings.<>c__DisplayClass30_0.<LoadComplete>b__5() in /home/runner/work/osu/osu/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs:line 204
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Graphics.Drawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Platform.GameHost.UpdateFrame()
   at osu.Framework.Threading.GameThread.processFrame()
--- End of stack trace from previous location ---
   at osu.Framework.Platform.GameHost.<>c__DisplayClass141_0.<abortExecutionFromException>b__0()
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Threading.GameThread.processFrame()
   at osu.Framework.Platform.ThreadRunner.RunMainLoop()
   at osu.Framework.Platform.GameHost.windowUpdate()
   at osu.Framework.Platform.GameHost.Run(Game game)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

Check failure on line 204 in osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs

View workflow job for this annotation

GitHub Actions / Results

osu.Game.Tests.Visual.Settings.TestSceneSettingsPanel ► TestFiltering(False)

Failed test found in: TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx Error: System.AggregateException : One or more errors occurred. (: ) ----> NUnit.Framework.AssertionException : :
Raw output
System.AggregateException : One or more errors occurred. (: )
  ----> NUnit.Framework.AssertionException : : 
   at osu.Framework.Testing.TestScene.UseTestSceneRunnerAttribute.AfterTest(ITest test)
   at NUnit.Framework.Internal.Commands.TestActionCommand.<>c__DisplayClass0_0.<.ctor>b__1(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__1()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
--AssertionException
   at osu.Framework.Logging.ThrowingTraceListener.Fail(String message1, String message2)
   at System.Diagnostics.TraceInternal.Fail(String message, String detailMessage)
   at System.Diagnostics.Debug.Fail(String message, String detailMessage)
   at osu.Game.Overlays.Settings.Sections.Graphics.LayoutSettings.<>c__DisplayClass30_0.<LoadComplete>b__5() in /home/runner/work/osu/osu/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs:line 204
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Graphics.Drawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
   at osu.Framework.Platform.GameHost.UpdateFrame()
   at osu.Framework.Threading.GameThread.processFrame()
--- End of stack trace from previous location ---
   at osu.Framework.Platform.GameHost.<>c__DisplayClass141_0.<abortExecutionFromException>b__0()
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Threading.GameThread.processFrame()
   at osu.Framework.Platform.ThreadRunner.RunMainLoop()
   at osu.Framework.Platform.GameHost.windowUpdate()
   at osu.Framework.Platform.GameHost.Run(Game game)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests have null window, so currentDisplay will have null value. Should be fine to make the bindable Bindable<Display?>.


resolutions.ReplaceRange(1, resolutions.Count - 1, display.NewValue.DisplayModes
.Where(m => m.Size.Width >= 800 && m.Size.Height >= 600)
Expand Down
2 changes: 1 addition & 1 deletion osu.Game/Screens/Edit/Components/BottomBarContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public partial class BottomBarContainer : Container

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;
Expand Down
2 changes: 1 addition & 1 deletion osu.Game/Screens/Edit/Setup/ColoursSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ protected override void LoadComplete()
syncingColours = true;

comboColours.Colours.Clear();
comboColours.Colours.AddRange(Beatmap.BeatmapSkin?.ComboColours);
comboColours.Colours.AddRange(Beatmap.BeatmapSkin?.ComboColours ?? []);

syncingColours = false;
});
Expand Down
4 changes: 2 additions & 2 deletions osu.Game/Screens/Edit/Timing/EffectSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ private void updateControlPointFromSlider(ValueChangedEvent<double> scrollSpeed)
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
{
Expand Down
2 changes: 1 addition & 1 deletion osu.Game/Screens/Edit/Timing/GroupSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal partial class GroupSection : CompositeDrawable
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!;
Expand Down
8 changes: 5 additions & 3 deletions osu.Game/Screens/Edit/Timing/Section.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -30,7 +31,7 @@ internal abstract partial class Section<T> : CompositeDrawable
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; }
Expand Down Expand Up @@ -103,12 +104,13 @@ protected override void LoadComplete()
}

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;
}
Expand All @@ -128,6 +130,6 @@ protected override void LoadComplete()

protected abstract void OnControlPointChanged(ValueChangedEvent<T?> point);

protected abstract T CreatePoint();
protected abstract T CreatePointFrom(double time);
}
}
2 changes: 1 addition & 1 deletion osu.Game/Screens/Edit/Timing/TapTimingControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public partial class TapTimingControl : CompositeDrawable
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();

Expand Down
4 changes: 2 additions & 2 deletions osu.Game/Screens/Edit/Timing/TimingSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ protected override void OnControlPointChanged(ValueChangedEvent<TimingControlPoi
}
}

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
{
Expand Down
5 changes: 5 additions & 0 deletions osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.ComponentModel;
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
Expand Down Expand Up @@ -38,6 +39,10 @@ public DrawableMatchRoom(Room room, bool allowEdit = true)
{
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);
}

Expand Down
3 changes: 2 additions & 1 deletion osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public bool FilterMods
}

[Resolved]
private IBindable<RulesetInfo> ruleset { get; set; } = null!;
private IBindable<RulesetInfo?> ruleset { get; set; } = null!;

[Resolved]
private IBindable<IReadOnlyList<Mod>> mods { get; set; } = null!;
Expand Down Expand Up @@ -186,6 +186,7 @@ private void subscribeToLocalScores(BeatmapInfo beatmapInfo, CancellationToken c
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)}"
Expand Down
6 changes: 3 additions & 3 deletions osu.Game/Screens/Select/SongSelect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public abstract partial class SongSelect : ScreenWithBeatmapBackground, IKeyBind

private FooterButtonOptions beatmapOptionsButton = null!;

private readonly Bindable<RulesetInfo> decoupledRuleset = new Bindable<RulesetInfo>();
private readonly Bindable<RulesetInfo?> decoupledRuleset = new Bindable<RulesetInfo?>();

private double audioFeedbackLastPlaybackTime;

Expand Down Expand Up @@ -426,7 +426,7 @@ protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnl

dependencies.CacheAs(this);
dependencies.CacheAs(decoupledRuleset);
dependencies.CacheAs<IBindable<RulesetInfo>>(decoupledRuleset);
dependencies.CacheAs<IBindable<RulesetInfo?>>(decoupledRuleset);

return dependencies;
}
Expand Down Expand Up @@ -994,7 +994,7 @@ private void bindBindables()

selectedMods.BindValueChanged(_ =>
{
if (decoupledRuleset.Value.Equals(rulesetNoDebounce))
if (decoupledRuleset.Value?.Equals(rulesetNoDebounce) ?? false)
advancedStats.Mods.Value = selectedMods.Value;
}, true);

Expand Down
2 changes: 1 addition & 1 deletion osu.Game/Skinning/SkinnableSprite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public SkinnableSprite()

SpriteName.BindValueChanged(name =>
{
((SpriteComponentLookup)ComponentLookup).LookupName = name.NewValue ?? string.Empty;
((SpriteComponentLookup)ComponentLookup).LookupName = name.NewValue;
if (IsLoaded)
SkinChanged(CurrentSkin);
});
Expand Down
Loading