Merge branch 'master' into readonly-dictionary-wrapper

This commit is contained in:
Bartłomiej Dach
2024-02-02 11:18:17 +01:00
committed by GitHub
47 changed files with 145 additions and 75 deletions

View File

@@ -9,7 +9,7 @@
]
},
"jetbrains.resharper.globaltools": {
"version": "2022.2.3",
"version": "2023.3.3",
"commands": [
"jb"
]

View File

@@ -1,5 +1,3 @@
is_global = true
# .NET Code Style
# IDE styles reference: https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/

View File

@@ -66,6 +66,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CompareOfFloatsByEqualityOperator/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertConditionalTernaryExpressionToSwitchExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertConstructorToMemberInitializers/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfDoToWhile/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToConditionalTernaryExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToNullCoalescingAssignment/@EntryIndexedValue">WARNING</s:String>
@@ -81,6 +82,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToConstant_002ELocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToLambdaExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToLocalFunction/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToPrimaryConstructor/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToStaticClass/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToUsingDeclaration/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertTypeCheckPatternToNullCheck/@EntryIndexedValue">DO_NOT_SHOW</s:String>
@@ -165,6 +167,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantImmediateDelegateInvocation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantLambdaSignatureParentheses/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantReadonlyModifier/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantTypeDeclarationBody/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantTypeSpecificationInDefaultExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantLinebreak/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantSpace/@EntryIndexedValue">WARNING</s:String>
@@ -250,6 +253,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedType_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseAwaitUsing/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseCollectionCountProperty/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseCollectionExpression/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseConfigureAwaitFalseForAsyncDisposable/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseFormatSpecifierInFormatString/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseFormatSpecifierInInterpolation/@EntryIndexedValue">WARNING</s:String>
@@ -262,6 +266,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UsePatternMatching/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseStringInterpolation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseUtf8StringLiteral/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseWithExpressionToCopyTuple/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VariableCanBeMadeConst/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VirtualMemberCallInConstructor/@EntryIndexedValue">HINT</s:String>

View File

@@ -22,28 +22,28 @@ namespace osu.Framework.Benchmarks
[Benchmark]
public void TestSprite()
{
var _ = new Sprite();
_ = new Sprite();
}
[Test]
[Benchmark]
public void TestCompositeDrawable()
{
var _ = new SimpleComposite();
_ = new SimpleComposite();
}
[Test]
[Benchmark]
public void TestContainer()
{
var _ = new Container();
_ = new Container();
}
[Test]
[Benchmark]
public void TestSpriteText()
{
var _ = new SpriteText();
_ = new SpriteText();
}
public partial class SimpleComposite : CompositeDrawable

View File

@@ -90,7 +90,7 @@ namespace osu.Framework.SourceGeneration.Tests
{
var newTree = CSharpSyntaxTree.ParseText(content, path: filename);
if (sources.ContainsKey(filename))
if (!sources.TryAdd(filename, newTree))
{
var oldTree = sources[filename];
sources[filename] = newTree;
@@ -104,7 +104,6 @@ namespace osu.Framework.SourceGeneration.Tests
}
else
{
sources.Add(filename, newTree);
Compilation = Compilation.AddSyntaxTrees(newTree);
}
}

View File

@@ -144,7 +144,7 @@ namespace FlappyDon.Game.Elements
if (GroundY > 0.0f)
groundPlane = GroundY / 2.0f;
else
groundPlane = Parent.DrawHeight - DrawHeight;
groundPlane = Parent!.DrawHeight - DrawHeight;
Y = Math.Min(Y, groundPlane);

View File

@@ -863,7 +863,8 @@ namespace osu.Framework.Tests.Bindables
[Test]
public void TestGetEnumeratorDoesNotReturnNull()
{
Assert.NotNull(bindableStringByteDictionary.GetEnumerator());
using var enumerator = bindableStringByteDictionary.GetEnumerator();
Assert.NotNull(enumerator);
}
[Test]
@@ -873,8 +874,10 @@ namespace osu.Framework.Tests.Bindables
var dict = new BindableDictionary<string, byte>(array);
var enumerator = dict.GetEnumerator();
using var enumerator = dict.GetEnumerator();
// ReSharper disable once NotDisposedResource
// Array enumerator is not disposable
Assert.AreNotEqual(array.GetEnumerator(), enumerator);
}

View File

@@ -1452,7 +1452,8 @@ namespace osu.Framework.Tests.Bindables
[Test]
public void TestGetEnumeratorDoesNotReturnNull()
{
Assert.NotNull(bindableStringList.GetEnumerator());
using var enumerator = bindableStringList.GetEnumerator();
Assert.NotNull(enumerator);
}
[Test]
@@ -1461,8 +1462,10 @@ namespace osu.Framework.Tests.Bindables
string[] array = { "" };
var list = new BindableList<string>(array);
var enumerator = list.GetEnumerator();
using var enumerator = list.GetEnumerator();
// ReSharper disable once NotDisposedResource
// Array enumerator is not disposable
Assert.AreNotEqual(array.GetEnumerator(), enumerator);
}

View File

@@ -29,9 +29,9 @@ namespace osu.Framework.Tests.Containers
{
Assert.Throws<InvalidOperationException>(() =>
{
var unused = new Container
_ = new Container
{
Children = (IReadOnlyList<Drawable>)Activator.CreateInstance(containerType)
Children = (IReadOnlyList<Drawable>)Activator.CreateInstance(containerType)!
};
});
@@ -39,12 +39,12 @@ namespace osu.Framework.Tests.Containers
{
var unused = new Container();
unused.AddRange((IEnumerable<Drawable>)Activator.CreateInstance(containerType));
unused.AddRange((IEnumerable<Drawable>)Activator.CreateInstance(containerType)!);
});
Assert.Throws<InvalidOperationException>(() =>
{
var unused = new AudioContainer
_ = new AudioContainer
{
Children = (IReadOnlyList<Drawable>)Activator.CreateInstance(containerType)!
};

View File

@@ -81,7 +81,7 @@ namespace osu.Framework.Tests.Containers
Child = new Container(),
};
var unused2 = new Container { Child = unused1.Child };
_ = new Container { Child = unused1.Child };
});
}

View File

@@ -355,7 +355,7 @@ namespace osu.Framework.Tests.IO
bool hasThrown = false;
request.Failed += exception => hasThrown = exception != null;
var _ = request.PerformAsync();
_ = request.PerformAsync();
Assert.DoesNotThrow(request.Abort);

View File

@@ -185,7 +185,7 @@ namespace osu.Framework.Tests.Visual.Audio
protected override void OnDrag(DragEvent e)
{
Y = (int)(e.MousePosition.Y / (Parent.DrawHeight / notes));
Y = (int)(e.MousePosition.Y / (Parent!.DrawHeight / notes));
}
public void Reset()

View File

@@ -47,7 +47,7 @@ namespace osu.Framework.Tests.Visual.Drawables
{
AddSliderStep("resize easings", default_size / 2, default_size * 2, default_size, size =>
{
easingsContainer?.Children?.OfType<Visualiser>().ForEach(easing => easing.ResizeTo(new Vector2(size)));
easingsContainer?.Children.OfType<Visualiser>().ForEach(easing => easing.ResizeTo(new Vector2(size)));
});
}

View File

@@ -243,7 +243,7 @@ namespace osu.Framework.Tests.Visual.Layout
{
for (int row = 0; row < getGrid().Content.Count; row++)
{
if (!Precision.AlmostEquals(expectedHeight, getGrid().Content[row][0].Parent.DrawHeight))
if (!Precision.AlmostEquals(expectedHeight, getGrid().Content[row][0].Parent!.DrawHeight))
return false;
}

View File

@@ -290,6 +290,43 @@ namespace osu.Framework.Tests.Visual.UserInterface
AddUntilStep("only one item", () => delayedList.ChildrenOfType<BasicRearrangeableListItem<int>>().Count() == 1);
}
[Test]
public void TestDragSynchronisation()
{
TestRearrangeableList another = null!;
addItems(3);
AddStep("add another list", () =>
{
another = new TestRearrangeableList
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Size = new Vector2(300, 200),
};
Add(another);
});
AddStep("bind lists", () =>
{
another.Items.BindTo(list.Items);
});
AddStep("move mouse to first dragger", () => InputManager.MoveMouseTo(getDragger(0)));
AddStep("begin a drag", () => InputManager.PressButton(MouseButton.Left));
AddStep("move the mouse", () => InputManager.MoveMouseTo(getDragger(0), new Vector2(0, 80)));
AddStep("end the drag", () => InputManager.ReleaseButton(MouseButton.Left));
AddUntilStep("0 is the last in original", () => list.Items.Last() == 0);
AddAssert("0 is the last in bound", () => another.Items.Last() == 0);
AddAssert("items flow updated", () =>
{
var item = (BasicRearrangeableListItem<int>)another.ListContainer.FlowingChildren.Last();
return item.Model == 0;
});
}
private void addDragSteps(int from, int to, int[] expectedSequence)
{
AddStep($"move to {from}", () =>

View File

@@ -70,29 +70,29 @@ namespace osu.Framework.Tests.Visual.UserInterface
AddStep("get tooltip instance", () => originalInstance = tooltipContainer.CurrentTooltip);
AddAssert("custom tooltip used", () => originalInstance.GetType() == typeof(CustomTooltip));
assertTooltipText(() => ((CustomContent)customTooltipTextA.TooltipContent).Text);
assertTooltipText(() => ((CustomContent)customTooltipTextA.TooltipContent!).Text);
hoverTooltipProvider(() => customTooltipTextB);
AddAssert("custom tooltip reused", () => tooltipContainer.CurrentTooltip == originalInstance);
assertTooltipText(() => ((CustomContent)customTooltipTextB.TooltipContent).Text);
assertTooltipText(() => ((CustomContent)customTooltipTextB.TooltipContent!).Text);
}
[Test]
public void TestDifferentCustomTooltips()
{
hoverTooltipProvider(() => customTooltipTextA);
assertTooltipText(() => ((CustomContent)customTooltipTextA.TooltipContent).Text);
assertTooltipText(() => ((CustomContent)customTooltipTextA.TooltipContent!).Text);
AddAssert("current tooltip type normal", () => tooltipContainer.CurrentTooltip.GetType() == typeof(CustomTooltip));
hoverTooltipProvider(() => customTooltipTextAlt);
assertTooltipText(() => ((CustomContent)customTooltipTextAlt.TooltipContent).Text);
assertTooltipText(() => ((CustomContent)customTooltipTextAlt.TooltipContent!).Text);
AddAssert("current tooltip type alt", () => tooltipContainer.CurrentTooltip.GetType() == typeof(CustomTooltipAlt));
hoverTooltipProvider(() => customTooltipTextB);
assertTooltipText(() => ((CustomContent)customTooltipTextB.TooltipContent).Text);
assertTooltipText(() => ((CustomContent)customTooltipTextB.TooltipContent!).Text);
AddAssert("current tooltip type normal", () => tooltipContainer.CurrentTooltip.GetType() == typeof(CustomTooltip));
}

View File

@@ -140,7 +140,7 @@ namespace osu.Framework.Allocation
public void Register(Type type, InjectDependencyDelegate injectDel, CacheDependencyDelegate cacheDel)
{
// The DependencyActivator constructor stores itself to a static dictionary.
var _ = new DependencyActivator(
_ = new DependencyActivator(
type,
injectDel ?? ((_, _) => { }),
cacheDel ?? ((_, d, _) => d));

View File

@@ -37,10 +37,7 @@ namespace osu.Framework.Audio.Sample
throw new ObjectDisposedException(ToString(), "Can not get a channel from a disposed sample.");
var channel = CreateChannel();
if (channel != null)
channel.OnPlay = onPlay;
channel.OnPlay = onPlay;
return channel;
}

View File

@@ -6,6 +6,7 @@
using System;
using System.Diagnostics;
using System.Globalization;
using JetBrains.Annotations;
using osu.Framework.Utils;
namespace osu.Framework.Bindables
@@ -13,6 +14,7 @@ namespace osu.Framework.Bindables
public class BindableNumber<T> : RangeConstrainedBindable<T>, IBindableNumber<T>
where T : struct, IComparable<T>, IConvertible, IEquatable<T>
{
[CanBeNull]
public event Action<T> PrecisionChanged;
public BindableNumber(T defaultValue = default)

View File

@@ -4,6 +4,7 @@
#nullable disable
using System;
using JetBrains.Annotations;
using osu.Framework.Bindables;
namespace osu.Framework.Configuration.Tracking
@@ -14,6 +15,7 @@ namespace osu.Framework.Configuration.Tracking
/// <typeparam name="TValue">The type of the tracked value.</typeparam>
public abstract class TrackedSetting<TValue> : ITrackedSetting
{
[CanBeNull]
public event Action<SettingDescription> SettingChanged;
private readonly object setting;

View File

@@ -7,6 +7,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using JetBrains.Annotations;
using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Effects;
@@ -132,7 +133,11 @@ namespace osu.Framework.Graphics.Containers
array[arrayIndex++] = c;
}
bool ICollection<T>.Remove(T item) => Remove(item, true);
bool ICollection<T>.Remove(T item)
{
ArgumentNullException.ThrowIfNull(item);
return Remove(item, true);
}
public Enumerator GetEnumerator() => new Enumerator(this);
@@ -297,7 +302,7 @@ namespace osu.Framework.Graphics.Containers
/// Removes a range of children. This is equivalent to calling <see cref="Remove(T, bool)"/> on
/// each element of the range in order.
/// </summary>
public void RemoveRange(IEnumerable<T> range, bool disposeImmediately)
public void RemoveRange([CanBeNull] IEnumerable<T> range, bool disposeImmediately)
{
if (range == null)
return;

View File

@@ -100,7 +100,7 @@ namespace osu.Framework.Graphics.Containers
loadDrawable(() => CreateDrawable(model) ?? Empty());
}
private void loadDrawable(Func<Drawable>? createDrawableFunc)
private void loadDrawable(Func<Drawable?>? createDrawableFunc)
{
// Remove the previous wrapper if the inner drawable hasn't finished loading.
if (currentWrapper?.DelayedLoadCompleted == false)
@@ -174,7 +174,7 @@ namespace osu.Framework.Graphics.Containers
/// <param name="createContentFunc">A function that creates the wrapped <see cref="Drawable"/>.</param>
/// <param name="timeBeforeLoad">The time before loading should begin.</param>
/// <returns>A <see cref="DelayedLoadWrapper"/> or null if <paramref name="createContentFunc"/> returns null.</returns>
private DelayedLoadWrapper createWrapper(Func<Drawable> createContentFunc, double timeBeforeLoad)
private DelayedLoadWrapper createWrapper(Func<Drawable?> createContentFunc, double timeBeforeLoad)
{
// Note that this only becomes null after the first consumption.
// ie. the `createContentFunc` cannot provide a null.
@@ -185,7 +185,7 @@ namespace osu.Framework.Graphics.Containers
try
{
// optimisation to use already constructed object (used above for null check).
return content ?? createContentFunc();
return content ?? createContentFunc()!;
}
finally
{

View File

@@ -110,6 +110,11 @@ namespace osu.Framework.Graphics.Containers
removeItems(e.OldItems);
addItems(e.NewItems);
break;
case NotifyCollectionChangedAction.Move:
sortItems();
OnItemsChanged();
break;
}
}
@@ -182,7 +187,7 @@ namespace osu.Framework.Graphics.Containers
// If the async load didn't complete, the item wouldn't exist in the container and an exception would be thrown
if (drawable.Parent == ListContainer)
ListContainer.SetLayoutPosition(drawable, i);
ListContainer!.SetLayoutPosition(drawable, i);
}
}

View File

@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace osu.Framework.Graphics.Containers
{
@@ -16,6 +17,8 @@ namespace osu.Framework.Graphics.Containers
public abstract class TextPart : ITextPart
{
public IEnumerable<Drawable> Drawables { get; }
[CanBeNull]
public event Action<IEnumerable<Drawable>> DrawablePartsRecreated;
private readonly List<Drawable> drawables = new List<Drawable>();

View File

@@ -238,7 +238,10 @@ namespace osu.Framework.Graphics
lock (LoadLock)
{
if (!isDirectAsyncContext && IsLongRunning)
throw new InvalidOperationException($"Tried to load long-running drawable type {GetType().ReadableName()} in a non-direct async context. See https://git.io/Je1YF for more details.");
{
throw new InvalidOperationException(
$"Tried to load long-running drawable type {GetType().ReadableName()} in a non-direct async context. See https://git.io/Je1YF for more details.");
}
if (IsDisposed)
throw new ObjectDisposedException(ToString(), "Attempting to load an already disposed drawable.");
@@ -1901,6 +1904,8 @@ namespace osu.Framework.Graphics
/// <returns>The vector in other's coordinates.</returns>
public Vector2 ToSpaceOfOtherDrawable(Vector2 input, IDrawable other)
{
ArgumentNullException.ThrowIfNull(other);
if (other == this)
return input;
@@ -1926,14 +1931,14 @@ namespace osu.Framework.Graphics
/// </summary>
/// <param name="input">A vector in local coordinates.</param>
/// <returns>The vector in Parent's coordinates.</returns>
public Vector2 ToParentSpace(Vector2 input) => ToSpaceOfOtherDrawable(input, Parent);
public Vector2 ToParentSpace(Vector2 input) => ToSpaceOfOtherDrawable(input, Parent!);
/// <summary>
/// Accepts a rectangle in local coordinates and converts it to a quad in Parent's space.
/// </summary>
/// <param name="input">A rectangle in local coordinates.</param>
/// <returns>The quad in Parent's coordinates.</returns>
public Quad ToParentSpace(RectangleF input) => ToSpaceOfOtherDrawable(input, Parent);
public Quad ToParentSpace(RectangleF input) => ToSpaceOfOtherDrawable(input, Parent!);
/// <summary>
/// Accepts a vector in local coordinates and converts it to coordinates in screen space.

View File

@@ -18,6 +18,7 @@ using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Graphics.Pooling;
using osu.Framework.Graphics.Rendering;
using osu.Framework.Platform;
@@ -70,6 +71,7 @@ namespace osu.Framework.Graphics.Performance
private FrameStatisticsMode state;
[CanBeNull]
public event Action<FrameStatisticsMode> StateChanged;
public FrameStatisticsMode State

View File

@@ -68,7 +68,7 @@ namespace osu.Framework.Graphics.Sprites
// Pre-cache the characters in the texture store
foreach (char character in localisedText.Value)
{
var unused = store.Get(font.FontName, character) ?? store.Get(null, character);
_ = store.Get(font.FontName, character) ?? store.Get(null, character);
}
}

View File

@@ -278,7 +278,7 @@ namespace osu.Framework.Graphics.Transforms
EnsureTransformMutationAllowed();
if (delay == 0)
return null;
return new ValueInvokeOnDisposal(() => { });
AddDelay(delay, recursive);
double newTransformDelay = TransformDelay;

View File

@@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Extensions.IEnumerableExtensions;
using osuTK.Graphics;
@@ -27,6 +28,7 @@ namespace osu.Framework.Graphics.UserInterface
/// <summary>
/// Invoked when this <see cref="Menu"/>'s <see cref="State"/> changes.
/// </summary>
[CanBeNull]
public event Action<MenuState> StateChanged;
/// <summary>
@@ -695,6 +697,7 @@ namespace osu.Framework.Graphics.UserInterface
/// <summary>
/// Invoked when this <see cref="DrawableMenuItem"/>'s <see cref="State"/> changes.
/// </summary>
[CanBeNull]
public event Action<MenuItemState> StateChanged;
/// <summary>

View File

@@ -597,7 +597,7 @@ namespace osu.Framework.Graphics.UserInterface
private int getCharacterClosestTo(Vector2 pos)
{
pos = Parent.ToSpaceOfOtherDrawable(pos, TextFlow);
pos = Parent!.ToSpaceOfOtherDrawable(pos, TextFlow);
int i = 0;

View File

@@ -405,7 +405,7 @@ namespace osu.Framework.Graphics.Veldrid
Debug.Assert(device.BackendType == GraphicsBackend.Vulkan);
var info = device.GetVulkanInfo();
var physicalDevice = info.PhysicalDevice;
IntPtr physicalDevice = info.PhysicalDevice;
uint instanceExtensionsCount = 0;
var result = VulkanNative.vkEnumerateInstanceExtensionProperties((byte*)null, ref instanceExtensionsCount, IntPtr.Zero);

View File

@@ -165,10 +165,8 @@ namespace osu.Framework.IO.Stores
return;
// Check if there's already a reload action bound
if (actionList.ContainsKey(name))
if (!actionList.TryAdd(name, onReload))
throw new InvalidOperationException($"A reload delegate is already bound to the resource '{name}'.");
actionList[name] = onReload;
}
/// <summary>

View File

@@ -9,7 +9,7 @@ namespace osu.Framework.Input.Bindings
{
public KeyCombination KeyCombination { get; set; }
public object Action { get; set; }
public object Action { get; set; } = null!;
/// <summary>
/// Construct a new instance.

View File

@@ -19,6 +19,7 @@ namespace osu.Framework.Lists
/// <summary>
/// Invoked when an element of the array is changed via <see cref="this[int]"/>.
/// </summary>
[CanBeNull]
public event Action ArrayElementChanged;
[NotNull]

View File

@@ -26,7 +26,7 @@ namespace osu.Framework.Physics
Origin = Anchor.Centre;
}
public Drawable Simulation { get; set; }
public Drawable Simulation { get; set; } = null!;
/// <summary>
/// Controls how elastic the material is. A value of 1 means perfect elasticity
@@ -96,7 +96,7 @@ namespace osu.Framework.Physics
/// </summary>
protected float ComputeI()
{
Matrix3 mat = DrawInfo.Matrix * Parent.DrawInfo.MatrixInverse;
Matrix3 mat = DrawInfo.Matrix * Parent!.DrawInfo.MatrixInverse;
Vector2 size = DrawSize;
// Inertial moment for a linearly transformed rectangle with a given size around its center.
@@ -256,7 +256,7 @@ namespace osu.Framework.Physics
/// </summary>
public void ReadState()
{
Matrix3 mat = Parent.DrawInfo.Matrix * ScreenToSimulationSpace;
Matrix3 mat = Parent!.DrawInfo.Matrix * ScreenToSimulationSpace;
Centre = Vector2Extensions.Transform(BoundingBox.Centre, mat);
RotationRadians = MathUtils.DegreesToRadians(Rotation); // TODO: Fix rotations
@@ -269,7 +269,7 @@ namespace osu.Framework.Physics
/// </summary>
public virtual void ApplyState()
{
Matrix3 mat = SimulationToScreenSpace * Parent.DrawInfo.MatrixInverse;
Matrix3 mat = SimulationToScreenSpace * Parent!.DrawInfo.MatrixInverse;
Position = Vector2Extensions.Transform(Centre, mat) + (Position - BoundingBox.Centre);
Rotation = MathUtils.RadiansToDegrees(RotationRadians); // TODO: Fix rotations
}

View File

@@ -27,7 +27,7 @@ namespace osu.Framework.Platform.MacOS
return IntPtr.Zero;
var result = generalPasteboard.ReadObjectsForClasses(classArray, null);
var objects = result?.ToArray();
IntPtr[]? objects = result?.ToArray();
return objects?.Length > 0 ? objects[0] : IntPtr.Zero;
}

View File

@@ -34,7 +34,7 @@ namespace osu.Framework.Platform.MacOS
base.Create();
// replace [SDLView scrollWheel:(NSEvent *)] with our own version
var viewClass = Class.Get("SDLView");
IntPtr viewClass = Class.Get("SDLView");
scrollWheelHandler = scrollWheel;
originalScrollWheel = Class.SwizzleMethod(viewClass, "scrollWheel:", "v@:@", scrollWheelHandler);
}

View File

@@ -22,7 +22,7 @@ namespace osu.Framework.Platform.MacOS.Native
public static IntPtr Get(string name)
{
var id = objc_getClass(name);
IntPtr id = objc_getClass(name);
if (id == IntPtr.Zero)
throw new ArgumentException("Unknown class: " + name);
@@ -48,12 +48,12 @@ namespace osu.Framework.Platform.MacOS.Native
/// <returns>A selector for the newly registered method, containing the old implementation.</returns>
public static IntPtr SwizzleMethod(IntPtr classHandle, string selector, string typeString, Delegate action)
{
var targetSelector = Selector.Get(selector);
var targetMethod = class_getInstanceMethod(classHandle, targetSelector);
var newMethodImplementation = Marshal.GetFunctionPointerForDelegate(action);
var newSelector = Selector.Get($"orig_{selector}");
IntPtr targetSelector = Selector.Get(selector);
IntPtr targetMethod = class_getInstanceMethod(classHandle, targetSelector);
IntPtr newMethodImplementation = Marshal.GetFunctionPointerForDelegate(action);
IntPtr newSelector = Selector.Get($"orig_{selector}");
class_replaceMethod(classHandle, newSelector, newMethodImplementation, typeString);
var newMethod = class_getInstanceMethod(classHandle, newSelector);
IntPtr newMethod = class_getInstanceMethod(classHandle, newSelector);
method_exchangeImplementations(targetMethod, newMethod);
return newSelector;
}

View File

@@ -110,7 +110,7 @@ namespace osu.Framework.Platform.MacOS.Native
fixed (char* ptrFirstChar = str)
{
var handle = SendIntPtr(Class.Get("NSString"), Selector.Get("alloc"));
IntPtr handle = SendIntPtr(Class.Get("NSString"), Selector.Get("alloc"));
return SendIntPtr(handle, Selector.Get("initWithCharacters:length:"), (IntPtr)ptrFirstChar, str.Length);
}
}
@@ -125,7 +125,7 @@ namespace osu.Framework.Platform.MacOS.Native
image.Save(stream, TiffFormat.Instance);
byte[] array = stream.ToArray();
var handle = SendIntPtr(Class.Get("NSImage"), Selector.Get("alloc"));
IntPtr handle = SendIntPtr(Class.Get("NSImage"), Selector.Get("alloc"));
return SendIntPtr(handle, Selector.Get("initWithData:"), NSData.FromBytes(array));
}
}

View File

@@ -26,7 +26,7 @@ namespace osu.Framework.Platform.MacOS.Native
internal static NSArray ArrayWithObjects(IntPtr[] objs)
{
var mutableArray = Cocoa.SendIntPtr(mutable_class_pointer, sel_array);
IntPtr mutableArray = Cocoa.SendIntPtr(mutable_class_pointer, sel_array);
foreach (IntPtr obj in objs)
Cocoa.SendVoid(mutableArray, sel_add_object, obj);
return new NSArray(mutableArray);

View File

@@ -22,7 +22,7 @@ namespace osu.Framework.Platform.MacOS.Native
internal byte[] ToBytes()
{
var pointer = Cocoa.SendIntPtr(Handle, sel_bytes);
IntPtr pointer = Cocoa.SendIntPtr(Handle, sel_bytes);
int size = Cocoa.SendInt(Handle, sel_length);
byte[] bytes = new byte[size];
@@ -34,7 +34,7 @@ namespace osu.Framework.Platform.MacOS.Native
{
fixed (byte* ptr = bytes)
{
var handle = Cocoa.SendIntPtr(class_pointer, sel_data_with_bytes, (IntPtr)ptr, (ulong)bytes.LongLength);
IntPtr handle = Cocoa.SendIntPtr(class_pointer, sel_data_with_bytes, (IntPtr)ptr, (ulong)bytes.LongLength);
return new NSData(handle);
}
}

View File

@@ -30,7 +30,7 @@ namespace osu.Framework.Platform.MacOS.Native
internal NSArray? ReadObjectsForClasses(NSArray classArray, NSDictionary? optionDict)
{
var result = Cocoa.SendIntPtr(Handle, sel_read_objects_for_classes, classArray.Handle, optionDict?.Handle ?? IntPtr.Zero);
IntPtr result = Cocoa.SendIntPtr(Handle, sel_read_objects_for_classes, classArray.Handle, optionDict?.Handle ?? IntPtr.Zero);
return result == IntPtr.Zero ? null : new NSArray(result);
}

View File

@@ -1022,7 +1022,7 @@ namespace osu.Framework.Platform.SDL2
/// <returns><c>true</c> if the <paramref name="bytePointer"/> was successfully converted to a string.</returns>
public static unsafe bool TryGetStringFromBytePointer(byte* bytePointer, out string str)
{
var ptr = new IntPtr(bytePointer);
IntPtr ptr = new IntPtr(bytePointer);
if (ptr == IntPtr.Zero)
{

View File

@@ -131,7 +131,7 @@ namespace osu.Framework.Platform.SDL2
var namesInfo = type.GetRuntimeFields().First(x => x.Name == "_EntryPointNamesInstance");
var offsetsInfo = type.GetRuntimeFields().First(x => x.Name == "_EntryPointNameOffsetsInstance");
var entryPointsInstance = (IntPtr[]?)pointsInfo.GetValue(bindings);
IntPtr[]? entryPointsInstance = (IntPtr[]?)pointsInfo.GetValue(bindings);
byte[]? entryPointNamesInstance = (byte[]?)namesInfo.GetValue(bindings);
int[]? entryPointNameOffsetsInstance = (int[]?)offsetsInfo.GetValue(bindings);

View File

@@ -315,9 +315,9 @@ namespace osu.Framework.Platform
if (controllers.ContainsKey(instanceID))
return;
var joystick = SDL.SDL_JoystickOpen(which);
IntPtr joystick = SDL.SDL_JoystickOpen(which);
var controller = IntPtr.Zero;
IntPtr controller = IntPtr.Zero;
if (SDL.SDL_IsGameController(which) == SDL.SDL_bool.SDL_TRUE)
controller = SDL.SDL_GameControllerOpen(which);

View File

@@ -72,7 +72,7 @@ namespace osu.Framework.Platform.Windows
public override void SetText(string text)
{
int bytes = (text.Length + 1) * 2;
var source = Marshal.StringToHGlobalUni(text);
IntPtr source = Marshal.StringToHGlobalUni(text);
setClipboard(source, bytes, cf_unicodetext);
}
@@ -119,11 +119,11 @@ namespace osu.Framework.Platform.Windows
EmptyClipboard();
// IMPORTANT: SetClipboardData requires memory that was acquired with GlobalAlloc using GMEM_MOVABLE.
var hGlobal = GlobalAlloc(ghnd, (UIntPtr)bytes);
IntPtr hGlobal = GlobalAlloc(ghnd, (UIntPtr)bytes);
try
{
var target = GlobalLock(hGlobal);
IntPtr target = GlobalLock(hGlobal);
if (target == IntPtr.Zero)
return false;

View File

@@ -94,6 +94,8 @@ namespace osu.Framework.Testing
public override void Add(Drawable drawable)
{
ArgumentNullException.ThrowIfNull(drawable);
if (drawable is Game)
throw new InvalidOperationException($"Use {nameof(AddGame)} when testing a game instance.");