1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 17:27:24 +08:00

Merge branch 'master' into remove-hud-component-lookup

This commit is contained in:
Dean Herbert 2021-06-02 16:10:06 +09:00 committed by GitHub
commit 5366e7f61e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 185 additions and 84 deletions

View File

@ -97,7 +97,7 @@ Before committing your code, please run a code formatter. This can be achieved b
We have adopted some cross-platform, compiler integrated analyzers. They can provide warnings when you are editing, building inside IDE or from command line, as-if they are provided by the compiler itself. We have adopted some cross-platform, compiler integrated analyzers. They can provide warnings when you are editing, building inside IDE or from command line, as-if they are provided by the compiler itself.
JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`, which is [only supported on Windows](https://youtrack.jetbrains.com/issue/RSRP-410004). Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice. JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`. Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice.
## Contributing ## Contributing

View File

@ -10,7 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -10,7 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -10,7 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -10,7 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -52,6 +52,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.525.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.525.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.528.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2021.601.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" /> <PackageReference Include="BenchmarkDotNet" Version="0.13.0" />
<PackageReference Include="nunit" Version="3.13.2" /> <PackageReference Include="nunit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
</ItemGroup> </ItemGroup>

View File

@ -2,7 +2,7 @@
<Import Project="..\osu.TestProject.props" /> <Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -2,7 +2,7 @@
<Import Project="..\osu.TestProject.props" /> <Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -2,7 +2,7 @@
<Import Project="..\osu.TestProject.props" /> <Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -182,8 +182,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
// todo: temporary / arbitrary, used for lifetime optimisation. // todo: temporary / arbitrary, used for lifetime optimisation.
this.Delay(800).FadeOut(); this.Delay(800).FadeOut();
(CirclePiece.Drawable as IMainCirclePiece)?.Animate(state);
switch (state) switch (state)
{ {
case ArmedState.Idle: case ArmedState.Idle:

View File

@ -97,8 +97,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
base.UpdateHitStateTransforms(state); base.UpdateHitStateTransforms(state);
(CirclePiece.Drawable as IMainCirclePiece)?.Animate(state);
switch (state) switch (state)
{ {
case ArmedState.Idle: case ArmedState.Idle:

View File

@ -87,8 +87,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Debug.Assert(HitObject.HitWindows != null); Debug.Assert(HitObject.HitWindows != null);
(CirclePiece.Drawable as IMainCirclePiece)?.Animate(state);
switch (state) switch (state)
{ {
case ArmedState.Idle: case ArmedState.Idle:

View File

@ -1,17 +0,0 @@
// 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 osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Skinning.Default
{
public interface IMainCirclePiece
{
/// <summary>
/// Begins animating this <see cref="IMainCirclePiece"/>.
/// </summary>
/// <param name="state">The <see cref="ArmedState"/> of the related <see cref="DrawableHitCircle"/>.</param>
void Animate(ArmedState state);
}
}

View File

@ -13,7 +13,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Skinning.Default namespace osu.Game.Rulesets.Osu.Skinning.Default
{ {
public class MainCirclePiece : CompositeDrawable, IMainCirclePiece public class MainCirclePiece : CompositeDrawable
{ {
private readonly CirclePiece circle; private readonly CirclePiece circle;
private readonly RingPiece ring; private readonly RingPiece ring;
@ -42,6 +42,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
private readonly IBindable<Color4> accentColour = new Bindable<Color4>(); private readonly IBindable<Color4> accentColour = new Bindable<Color4>();
private readonly IBindable<int> indexInCurrentCombo = new Bindable<int>(); private readonly IBindable<int> indexInCurrentCombo = new Bindable<int>();
private readonly IBindable<ArmedState> armedState = new Bindable<ArmedState>();
[Resolved] [Resolved]
private DrawableHitObject drawableObject { get; set; } private DrawableHitObject drawableObject { get; set; }
@ -53,6 +54,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
accentColour.BindTo(drawableObject.AccentColour); accentColour.BindTo(drawableObject.AccentColour);
indexInCurrentCombo.BindTo(drawableOsuObject.IndexInCurrentComboBindable); indexInCurrentCombo.BindTo(drawableOsuObject.IndexInCurrentComboBindable);
armedState.BindTo(drawableObject.State);
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -67,16 +69,20 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
}, true); }, true);
indexInCurrentCombo.BindValueChanged(index => number.Text = (index.NewValue + 1).ToString(), true); indexInCurrentCombo.BindValueChanged(index => number.Text = (index.NewValue + 1).ToString(), true);
armedState.BindValueChanged(animate, true);
} }
public void Animate(ArmedState state) private void animate(ValueChangedEvent<ArmedState> state)
{ {
ClearTransforms(true);
using (BeginAbsoluteSequence(drawableObject.StateUpdateTime)) using (BeginAbsoluteSequence(drawableObject.StateUpdateTime))
glow.FadeOut(400); glow.FadeOut(400);
using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime)) using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime))
{ {
switch (state) switch (state.NewValue)
{ {
case ArmedState.Hit: case ArmedState.Hit:
const double flash_in = 40; const double flash_in = 40;
@ -89,7 +95,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
explode.FadeIn(flash_in); explode.FadeIn(flash_in);
this.ScaleTo(1.5f, 400, Easing.OutQuad); this.ScaleTo(1.5f, 400, Easing.OutQuad);
using (BeginDelayedSequence(flash_in, true)) using (BeginDelayedSequence(flash_in))
{ {
// after the flash, we can hide some elements that were behind it // after the flash, we can hide some elements that were behind it
ring.FadeOut(); ring.FadeOut();

View File

@ -12,7 +12,6 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Skinning.Default;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -20,7 +19,7 @@ using static osu.Game.Skinning.LegacySkinConfiguration;
namespace osu.Game.Rulesets.Osu.Skinning.Legacy namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{ {
public class LegacyMainCirclePiece : CompositeDrawable, IMainCirclePiece public class LegacyMainCirclePiece : CompositeDrawable
{ {
private readonly string priorityLookup; private readonly string priorityLookup;
private readonly bool hasNumber; private readonly bool hasNumber;
@ -41,6 +40,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
private readonly Bindable<Color4> accentColour = new Bindable<Color4>(); private readonly Bindable<Color4> accentColour = new Bindable<Color4>();
private readonly IBindable<int> indexInCurrentCombo = new Bindable<int>(); private readonly IBindable<int> indexInCurrentCombo = new Bindable<int>();
private readonly IBindable<ArmedState> armedState = new Bindable<ArmedState>();
[Resolved] [Resolved]
private DrawableHitObject drawableObject { get; set; } private DrawableHitObject drawableObject { get; set; }
@ -115,6 +115,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
accentColour.BindTo(drawableObject.AccentColour); accentColour.BindTo(drawableObject.AccentColour);
indexInCurrentCombo.BindTo(drawableOsuObject.IndexInCurrentComboBindable); indexInCurrentCombo.BindTo(drawableOsuObject.IndexInCurrentComboBindable);
armedState.BindTo(drawableObject.State);
Texture getTextureWithFallback(string name) Texture getTextureWithFallback(string name)
{ {
@ -139,15 +140,19 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
accentColour.BindValueChanged(colour => hitCircleSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); accentColour.BindValueChanged(colour => hitCircleSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true);
if (hasNumber) if (hasNumber)
indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true);
armedState.BindValueChanged(animate, true);
} }
public void Animate(ArmedState state) private void animate(ValueChangedEvent<ArmedState> state)
{ {
const double legacy_fade_duration = 240; const double legacy_fade_duration = 240;
using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime, true)) ClearTransforms(true);
using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime))
{ {
switch (state) switch (state.NewValue)
{ {
case ArmedState.Hit: case ArmedState.Hit:
circleSprites.FadeOut(legacy_fade_duration, Easing.Out); circleSprites.FadeOut(legacy_fade_duration, Easing.Out);

View File

@ -2,7 +2,7 @@
<Import Project="..\osu.TestProject.props" /> <Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -489,5 +489,23 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual(result.Links[2].Url, "\uD83D\uDE00"); Assert.AreEqual(result.Links[2].Url, "\uD83D\uDE00");
Assert.AreEqual(result.Links[3].Url, "\uD83D\uDE20"); Assert.AreEqual(result.Links[3].Url, "\uD83D\uDE20");
} }
[Test]
public void TestAbsoluteExternalLinks()
{
LinkDetails result = MessageFormatter.GetLinkDetails("https://google.com");
Assert.AreEqual(LinkAction.External, result.Action);
Assert.AreEqual("https://google.com", result.Argument);
}
[Test]
public void TestRelativeExternalLinks()
{
LinkDetails result = MessageFormatter.GetLinkDetails("/relative");
Assert.AreEqual(LinkAction.External, result.Action);
Assert.AreEqual("/relative", result.Argument);
}
} }
} }

View File

@ -92,6 +92,41 @@ namespace osu.Game.Tests.Gameplay
AddAssert("Lifetime is correct", () => dho.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY && entry.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY); AddAssert("Lifetime is correct", () => dho.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY && entry.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY);
} }
[Test]
public void TestDrawableLifetimeUpdateOnEntryLifetimeChange()
{
TestDrawableHitObject dho = null;
TestLifetimeEntry entry = null;
AddStep("Create DHO", () =>
{
dho = new TestDrawableHitObject(null);
dho.Apply(entry = new TestLifetimeEntry(new HitObject()));
Child = dho;
});
AddStep("Set entry lifetime", () =>
{
entry.LifetimeStart = 777;
entry.LifetimeEnd = 888;
});
AddAssert("Drawable lifetime is updated", () => dho.LifetimeStart == 777 && dho.LifetimeEnd == 888);
AddStep("KeepAlive = true", () => entry.KeepAlive = true);
AddAssert("Drawable lifetime is updated", () => dho.LifetimeStart == double.MinValue && dho.LifetimeEnd == double.MaxValue);
AddStep("Modify start time", () => entry.HitObject.StartTime = 100);
AddAssert("Drawable lifetime is correct", () => dho.LifetimeStart == double.MinValue);
AddStep("Set LifetimeStart", () => dho.LifetimeStart = 666);
AddAssert("Lifetime change is blocked", () => dho.LifetimeStart == double.MinValue);
AddStep("Set LifetimeEnd", () => dho.LifetimeEnd = 999);
AddAssert("Lifetime change is blocked", () => dho.LifetimeEnd == double.MaxValue);
AddStep("KeepAlive = false", () => entry.KeepAlive = false);
AddAssert("Drawable lifetime is restored", () => dho.LifetimeStart == 666 && dho.LifetimeEnd == 999);
}
private class TestDrawableHitObject : DrawableHitObject private class TestDrawableHitObject : DrawableHitObject
{ {
public const double INITIAL_LIFETIME_OFFSET = 100; public const double INITIAL_LIFETIME_OFFSET = 100;

View File

@ -90,6 +90,20 @@ namespace osu.Game.Tests.Visual.Gameplay
assertChildPosition(5); assertChildPosition(5);
} }
[TestCase("pooled")]
[TestCase("non-pooled")]
public void TestLifetimeRecomputedWhenTimeRangeChanges(string pooled)
{
var beatmap = createBeatmap(_ => pooled == "pooled" ? new TestPooledHitObject() : new TestHitObject());
beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = time_range });
createTest(beatmap);
assertDead(3);
AddStep("increase time range", () => drawableRuleset.TimeRange.Value = 3 * time_range);
assertPosition(3, 1);
}
[Test] [Test]
public void TestRelativeBeatLengthScaleSingleTimingPoint() public void TestRelativeBeatLengthScaleSingleTimingPoint()
{ {

View File

@ -3,7 +3,7 @@
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="DeepEqual" Version="2.0.0" /> <PackageReference Include="DeepEqual" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -5,7 +5,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
</ItemGroup> </ItemGroup>

View File

@ -43,7 +43,7 @@ namespace osu.Game.Graphics.Containers
AddText(text[previousLinkEnd..link.Index]); AddText(text[previousLinkEnd..link.Index]);
string displayText = text.Substring(link.Index, link.Length); string displayText = text.Substring(link.Index, link.Length);
string linkArgument = link.Argument ?? link.Url; string linkArgument = link.Argument;
string tooltip = displayText == link.Url ? null : link.Url; string tooltip = displayText == link.Url ? null : link.Url;
AddLink(displayText, link.Action, linkArgument, tooltip); AddLink(displayText, link.Action, linkArgument, tooltip);
@ -57,7 +57,7 @@ namespace osu.Game.Graphics.Containers
createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.External, url), url); createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.External, url), url);
public void AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null) public void AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
=> createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.Custom, null), tooltipText, action); => createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.Custom, string.Empty), tooltipText, action);
public void AddLink(string text, LinkAction action, string argument, string tooltipText = null, Action<SpriteText> creationParameters = null) public void AddLink(string text, LinkAction action, string argument, string tooltipText = null, Action<SpriteText> creationParameters = null)
=> createLink(AddText(text, creationParameters), new LinkDetails(action, argument), tooltipText); => createLink(AddText(text, creationParameters), new LinkDetails(action, argument), tooltipText);
@ -70,7 +70,7 @@ namespace osu.Game.Graphics.Containers
createLink(spriteText.Yield(), new LinkDetails(action, argument), tooltipText); createLink(spriteText.Yield(), new LinkDetails(action, argument), tooltipText);
} }
public void AddLink(IEnumerable<SpriteText> text, LinkAction action = LinkAction.External, string linkArgument = null, string tooltipText = null) public void AddLink(IEnumerable<SpriteText> text, LinkAction action, string linkArgument, string tooltipText = null)
{ {
foreach (var t in text) foreach (var t in text)
AddArbitraryDrawable(t); AddArbitraryDrawable(t);

View File

@ -4,7 +4,9 @@
using Markdig.Syntax.Inlines; using Markdig.Syntax.Inlines;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Containers.Markdown; using osu.Framework.Graphics.Containers.Markdown;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Overlays; using osu.Game.Overlays;
@ -12,17 +14,50 @@ namespace osu.Game.Graphics.Containers.Markdown
{ {
public class OsuMarkdownTextFlowContainer : MarkdownTextFlowContainer public class OsuMarkdownTextFlowContainer : MarkdownTextFlowContainer
{ {
[Resolved]
private OverlayColourProvider colourProvider { get; set; }
protected override void AddLinkText(string text, LinkInline linkInline) protected override void AddLinkText(string text, LinkInline linkInline)
=> AddDrawable(new OsuMarkdownLinkText(text, linkInline)); => AddDrawable(new OsuMarkdownLinkText(text, linkInline));
// TODO : Add background (colour B6) and change font to monospace // TODO : Change font to monospace
protected override void AddCodeInLine(CodeInline codeInline) protected override void AddCodeInLine(CodeInline codeInline) => AddDrawable(new OsuMarkdownInlineCode
=> AddText(codeInline.Content, t => { t.Colour = colourProvider.Light1; }); {
Text = codeInline.Content
});
protected override SpriteText CreateEmphasisedSpriteText(bool bold, bool italic) protected override SpriteText CreateEmphasisedSpriteText(bool bold, bool italic)
=> CreateSpriteText().With(t => t.Font = t.Font.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, italics: italic)); => CreateSpriteText().With(t => t.Font = t.Font.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, italics: italic));
private class OsuMarkdownInlineCode : Container
{
[Resolved]
private IMarkdownTextComponent parentTextComponent { get; set; }
public string Text;
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
AutoSizeAxes = Axes.Both;
CornerRadius = 4;
Masking = true;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background6,
},
parentTextComponent.CreateSpriteText().With(t =>
{
t.Colour = colourProvider.Light1;
t.Text = Text;
t.Padding = new MarginPadding
{
Vertical = 1,
Horizontal = 4,
};
}),
};
}
}
} }
} }

View File

@ -6,6 +6,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
#nullable enable
namespace osu.Game.Online.Chat namespace osu.Game.Online.Chat
{ {
public static class MessageFormatter public static class MessageFormatter
@ -61,7 +63,7 @@ namespace osu.Game.Online.Chat
private static string websiteRootUrl = "osu.ppy.sh"; private static string websiteRootUrl = "osu.ppy.sh";
private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null, char[] escapeChars = null) private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null, char[]? escapeChars = null)
{ {
int captureOffset = 0; int captureOffset = 0;
@ -173,12 +175,12 @@ namespace osu.Game.Online.Chat
} }
} }
return new LinkDetails(LinkAction.External, url); break;
case "osu": case "osu":
// every internal link also needs some kind of argument // every internal link also needs some kind of argument
if (args.Length < 3) if (args.Length < 3)
return new LinkDetails(LinkAction.External, null); break;
LinkAction linkType; LinkAction linkType;
@ -220,7 +222,7 @@ namespace osu.Game.Online.Chat
return new LinkDetails(LinkAction.JoinMultiplayerMatch, args[1]); return new LinkDetails(LinkAction.JoinMultiplayerMatch, args[1]);
} }
return new LinkDetails(LinkAction.External, null); return new LinkDetails(LinkAction.External, url);
} }
private static MessageFormatterResult format(string toFormat, int startIndex = 0, int space = 3) private static MessageFormatterResult format(string toFormat, int startIndex = 0, int space = 3)

View File

@ -277,7 +277,7 @@ namespace osu.Game
{ {
case LinkAction.OpenBeatmap: case LinkAction.OpenBeatmap:
// TODO: proper query params handling // TODO: proper query params handling
if (link.Argument != null && int.TryParse(link.Argument.Contains('?') ? link.Argument.Split('?')[0] : link.Argument, out int beatmapId)) if (int.TryParse(link.Argument.Contains('?') ? link.Argument.Split('?')[0] : link.Argument, out int beatmapId))
ShowBeatmap(beatmapId); ShowBeatmap(beatmapId);
break; break;

View File

@ -35,11 +35,11 @@ namespace osu.Game.Rulesets.Objects
HitObject = hitObject; HitObject = hitObject;
startTimeBindable.BindTo(HitObject.StartTimeBindable); startTimeBindable.BindTo(HitObject.StartTimeBindable);
startTimeBindable.BindValueChanged(_ => setInitialLifetime(), true); startTimeBindable.BindValueChanged(_ => SetInitialLifetime(), true);
// Subscribe to this event before the DrawableHitObject so that the local callback is invoked before the entry is re-applied as a result of DefaultsApplied. // Subscribe to this event before the DrawableHitObject so that the local callback is invoked before the entry is re-applied as a result of DefaultsApplied.
// This way, the DrawableHitObject can use OnApply() to overwrite the LifetimeStart that was set inside setInitialLifetime(). // This way, the DrawableHitObject can use OnApply() to overwrite the LifetimeStart that was set inside setInitialLifetime().
HitObject.DefaultsApplied += _ => setInitialLifetime(); HitObject.DefaultsApplied += _ => SetInitialLifetime();
} }
// The lifetime, as set by the hitobject. // The lifetime, as set by the hitobject.
@ -94,6 +94,6 @@ namespace osu.Game.Rulesets.Objects
/// <summary> /// <summary>
/// Set <see cref="LifetimeEntry.LifetimeStart"/> using <see cref="InitialLifetimeOffset"/>. /// Set <see cref="LifetimeEntry.LifetimeStart"/> using <see cref="InitialLifetimeOffset"/>.
/// </summary> /// </summary>
private void setInitialLifetime() => LifetimeStart = HitObject.StartTime - InitialLifetimeOffset; internal void SetInitialLifetime() => LifetimeStart = HitObject.StartTime - InitialLifetimeOffset;
} }
} }

View File

@ -3,6 +3,7 @@
#nullable enable #nullable enable
using System;
using System.Diagnostics; using System.Diagnostics;
using osu.Framework.Graphics.Performance; using osu.Framework.Graphics.Performance;
using osu.Framework.Graphics.Pooling; using osu.Framework.Graphics.Pooling;
@ -26,14 +27,13 @@ namespace osu.Game.Rulesets.Objects.Pooling
/// </summary> /// </summary>
protected bool HasEntryApplied { get; private set; } protected bool HasEntryApplied { get; private set; }
// Drawable's lifetime gets out of sync with entry's lifetime if entry's lifetime is modified.
// We cannot delegate getter to `Entry.LifetimeStart` because it is incompatible with `LifetimeManagementContainer` due to how lifetime change is detected.
public override double LifetimeStart public override double LifetimeStart
{ {
get => base.LifetimeStart; get => base.LifetimeStart;
set set
{ {
base.LifetimeStart = value; if (Entry == null && LifetimeStart != value)
throw new InvalidOperationException($"Cannot modify lifetime of {nameof(PoolableDrawableWithLifetime<TEntry>)} when entry is not set");
if (Entry != null) if (Entry != null)
Entry.LifetimeStart = value; Entry.LifetimeStart = value;
@ -45,7 +45,8 @@ namespace osu.Game.Rulesets.Objects.Pooling
get => base.LifetimeEnd; get => base.LifetimeEnd;
set set
{ {
base.LifetimeEnd = value; if (Entry == null && LifetimeEnd != value)
throw new InvalidOperationException($"Cannot modify lifetime of {nameof(PoolableDrawableWithLifetime<TEntry>)} when entry is not set");
if (Entry != null) if (Entry != null)
Entry.LifetimeEnd = value; Entry.LifetimeEnd = value;
@ -79,9 +80,8 @@ namespace osu.Game.Rulesets.Objects.Pooling
free(); free();
Entry = entry; Entry = entry;
entry.LifetimeChanged += setLifetimeFromEntry;
base.LifetimeStart = entry.LifetimeStart; setLifetimeFromEntry(entry);
base.LifetimeEnd = entry.LifetimeEnd;
OnApply(entry); OnApply(entry);
@ -117,11 +117,19 @@ namespace osu.Game.Rulesets.Objects.Pooling
OnFree(Entry); OnFree(Entry);
Entry.LifetimeChanged -= setLifetimeFromEntry;
Entry = null; Entry = null;
base.LifetimeStart = double.MinValue; base.LifetimeStart = double.MinValue;
base.LifetimeEnd = double.MaxValue; base.LifetimeEnd = double.MaxValue;
HasEntryApplied = false; HasEntryApplied = false;
} }
private void setLifetimeFromEntry(LifetimeEntry entry)
{
Debug.Assert(entry == Entry);
base.LifetimeStart = entry.LifetimeStart;
base.LifetimeEnd = entry.LifetimeEnd;
}
} }
} }

View File

@ -172,11 +172,12 @@ namespace osu.Game.Rulesets.UI.Scrolling
if (layoutCache.IsValid) return; if (layoutCache.IsValid) return;
foreach (var hitObject in Objects) layoutComputed.Clear();
{
if (hitObject.HitObject != null) // Reset lifetime to the conservative estimation.
invalidateHitObject(hitObject); // If a drawable becomes alive by this lifetime, its lifetime will be updated to a more precise lifetime in the next update.
} foreach (var entry in Entries)
entry.SetInitialLifetime();
scrollingInfo.Algorithm.Reset(); scrollingInfo.Algorithm.Reset();

View File

@ -20,23 +20,23 @@
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="DiffPlex" Version="1.7.0" /> <PackageReference Include="DiffPlex" Version="1.7.0" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.33" /> <PackageReference Include="HtmlAgilityPack" Version="1.11.33" />
<PackageReference Include="Humanizer" Version="2.8.26" /> <PackageReference Include="Humanizer" Version="2.10.1" />
<PackageReference Include="MessagePack" Version="2.2.85" /> <PackageReference Include="MessagePack" Version="2.2.85" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.5" /> <PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.6" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.5" /> <PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.6" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="5.0.5" /> <PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="5.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" /> <PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="ppy.LocalisationAnalyser" Version="2021.524.0"> <PackageReference Include="ppy.LocalisationAnalyser" Version="2021.525.0">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="ppy.osu.Framework" Version="2021.528.0" /> <PackageReference Include="ppy.osu.Framework" Version="2021.601.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.525.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.525.0" />
<PackageReference Include="Sentry" Version="3.3.4" /> <PackageReference Include="Sentry" Version="3.4.0" />
<PackageReference Include="SharpCompress" Version="0.28.2" /> <PackageReference Include="SharpCompress" Version="0.28.2" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />

View File

@ -70,7 +70,7 @@
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.528.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2021.601.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.525.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.525.0" />
</ItemGroup> </ItemGroup>
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) --> <!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
@ -89,11 +89,11 @@
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. --> <!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
<ItemGroup Label="Transitive Dependencies"> <ItemGroup Label="Transitive Dependencies">
<PackageReference Include="DiffPlex" Version="1.6.3" /> <PackageReference Include="DiffPlex" Version="1.6.3" />
<PackageReference Include="Humanizer" Version="2.8.26" /> <PackageReference Include="Humanizer" Version="2.10.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Framework" Version="2021.528.0" /> <PackageReference Include="ppy.osu.Framework" Version="2021.601.0" />
<PackageReference Include="SharpCompress" Version="0.28.2" /> <PackageReference Include="SharpCompress" Version="0.28.2" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />