1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-14 07:32:36 +08:00

Compare commits

..

1 Commits

120 changed files with 1064 additions and 1195 deletions
+4 -1
View File
@@ -1,3 +1,6 @@
[submodule "osu-framework"]
path = osu-framework
url = https://github.com/ppy/osu-framework
[submodule "osu-resources"]
path = osu-resources
url = https://github.com/ppy/osu-resources
url = https://github.com/ppy/osu-resources
@@ -1,17 +1,21 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="RulesetTests (catch)" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll" />
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/net471/osu.Game.Rulesets.Catch.Tests.exe" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<envs>
<env name="ASPNETCORE_ENVIRONMENT" value="Development" />
<env name="ASPNETCORE_URLS" value="http://localhost:5000" />
</envs>
<option name="USE_MONO" value="0" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj" />
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
<option name="PROJECT_TFM" value=".NETFramework,Version=v4.7.1" />
<browser url="http://localhost:5000" />
<method />
</configuration>
@@ -1,17 +1,21 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="RulesetTests (mania)" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll" />
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/net471/osu.Game.Rulesets.Mania.Tests.exe" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<envs>
<env name="ASPNETCORE_ENVIRONMENT" value="Development" />
<env name="ASPNETCORE_URLS" value="http://localhost:5000" />
</envs>
<option name="USE_MONO" value="0" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj" />
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
<option name="PROJECT_TFM" value=".NETFramework,Version=v4.7.1" />
<browser url="http://localhost:5000" />
<method />
</configuration>
@@ -1,17 +1,21 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="RulesetTests (osu!)" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll" />
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/net471/osu.Game.Rulesets.Osu.Tests.exe" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<envs>
<env name="ASPNETCORE_ENVIRONMENT" value="Development" />
<env name="ASPNETCORE_URLS" value="http://localhost:5000" />
</envs>
<option name="USE_MONO" value="0" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj" />
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
<option name="PROJECT_TFM" value=".NETFramework,Version=v4.7.1" />
<browser url="http://localhost:5000" />
<method />
</configuration>
@@ -1,17 +1,21 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="RulesetTests (taiko)" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll" />
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/net471/osu.Game.Rulesets.Taiko.Tests.exe" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<envs>
<env name="ASPNETCORE_ENVIRONMENT" value="Development" />
<env name="ASPNETCORE_URLS" value="http://localhost:5000" />
</envs>
<option name="USE_MONO" value="0" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj" />
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
<option name="PROJECT_TFM" value=".NETFramework,Version=v4.7.1" />
<browser url="http://localhost:5000" />
<method />
</configuration>
@@ -0,0 +1,18 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="VisualTests (net471)" type="DotNetProject" factoryName=".NET Project" singleton="true">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/net471/osu.Game.Tests.exe" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
<option name="PASS_PARENT_ENVS" value="1" />
<envs />
<option name="USE_MONO" value="0" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Tests/osu.Game.Tests.csproj" />
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETFramework,Version=v4.7.1" />
<method />
</configuration>
</component>
@@ -0,0 +1,18 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="osu! (net471)" type="DotNetProject" factoryName=".NET Project" singleton="true">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net471/osu!.exe" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
<option name="PASS_PARENT_ENVS" value="1" />
<envs />
<option name="USE_MONO" value="0" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Desktop/osu.Desktop.csproj" />
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETFramework,Version=v4.7.1" />
<method />
</configuration>
</component>
+64 -8
View File
@@ -2,7 +2,63 @@
"version": "0.2.0",
"configurations": [
{
"name": "VisualTests (Debug)",
"name": "VisualTests (Debug, net471)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Game.Tests/bin/Debug/net471/osu.Game.Tests.exe",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug, msbuild)",
"runtimeExecutable": null,
"env": {},
"console": "internalConsole"
},
{
"name": "VisualTests (Release, net471)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Game.Tests/bin/Release/net471/osu.Game.Tests.exe",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release, msbuild)",
"runtimeExecutable": null,
"env": {},
"console": "internalConsole"
},
{
"name": "osu! (Debug, net471)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop/bin/Debug/net471/osu!.exe",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug, msbuild)",
"runtimeExecutable": null,
"env": {},
"console": "internalConsole"
},
{
"name": "osu! (Release, net471)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop/bin/Release/net471/osu!.exe",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release, msbuild)",
"runtimeExecutable": null,
"env": {},
"console": "internalConsole"
},
{
"name": "VisualTests (Debug, netcoreapp2.1)",
"type": "coreclr",
"request": "launch",
"program": "dotnet",
@@ -10,12 +66,12 @@
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Debug)",
"preLaunchTask": "Build tests (Debug, dotnet)",
"env": {},
"console": "internalConsole"
},
{
"name": "VisualTests (Release)",
"name": "VisualTests (Release, netcoreapp2.1)",
"type": "coreclr",
"request": "launch",
"program": "dotnet",
@@ -23,12 +79,12 @@
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1/osu.Game.Tests.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Release)",
"preLaunchTask": "Build tests (Release, dotnet)",
"env": {},
"console": "internalConsole"
},
{
"name": "osu! (Debug)",
"name": "osu! (Debug, netcoreapp2.1)",
"type": "coreclr",
"request": "launch",
"program": "dotnet",
@@ -36,12 +92,12 @@
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll",
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Debug)",
"preLaunchTask": "Build osu! (Debug, dotnet)",
"env": {},
"console": "internalConsole"
},
{
"name": "osu! (Release)",
"name": "osu! (Release, netcoreapp2.1)",
"type": "coreclr",
"request": "launch",
"program": "dotnet",
@@ -49,7 +105,7 @@
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll",
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Release)",
"preLaunchTask": "Build osu! (Release, dotnet)",
"env": {},
"console": "internalConsole"
}
+40 -4
View File
@@ -4,7 +4,34 @@
"version": "2.0.0",
"tasks": [
{
"label": "Build osu! (Debug)",
"label": "Build (Debug, msbuild)",
"type": "shell",
"command": "msbuild",
"args": [
"/p:TargetFramework=net471",
"/p:GenerateFullPaths=true",
"/m",
"/verbosity:m"
],
"group": "build",
"problemMatcher": "$msCompile"
},
{
"label": "Build (Release, msbuild)",
"type": "shell",
"command": "msbuild",
"args": [
"/p:Configuration=Release",
"/p:TargetFramework=net471",
"/p:GenerateFullPaths=true",
"/m",
"/verbosity:m"
],
"group": "build",
"problemMatcher": "$msCompile"
},
{
"label": "Build osu! (Debug, dotnet)",
"type": "shell",
"command": "dotnet",
"args": [
@@ -20,7 +47,7 @@
"problemMatcher": "$msCompile"
},
{
"label": "Build osu! (Release)",
"label": "Build osu! (Release, dotnet)",
"type": "shell",
"command": "dotnet",
"args": [
@@ -37,7 +64,7 @@
"problemMatcher": "$msCompile"
},
{
"label": "Build tests (Debug)",
"label": "Build tests (Debug, dotnet)",
"type": "shell",
"command": "dotnet",
"args": [
@@ -53,7 +80,7 @@
"problemMatcher": "$msCompile"
},
{
"label": "Build tests (Release)",
"label": "Build tests (Release, dotnet)",
"type": "shell",
"command": "dotnet",
"args": [
@@ -69,6 +96,15 @@
"group": "build",
"problemMatcher": "$msCompile"
},
{
"label": "Restore (net471)",
"type": "shell",
"command": "nuget",
"args": [
"restore"
],
"problemMatcher": []
},
{
"label": "Restore (netcoreapp2.1)",
"type": "shell",
+6 -1
View File
@@ -1,7 +1,12 @@
clone_depth: 1
version: '{branch}-{build}'
image: Visual Studio 2017
image: Visual Studio 2017 preview
configuration: Debug
cache:
- C:\ProgramData\chocolatey\bin -> appveyor.yml
- C:\ProgramData\chocolatey\lib -> appveyor.yml
- inspectcode -> appveyor.yml
- packages -> **\packages.config
install:
- cmd: git submodule update --init --recursive --depth=5
- cmd: choco install resharper-clt -y
+4 -2
View File
@@ -1,7 +1,9 @@
clone_depth: 1
version: '{build}'
skip_non_tags: true
# skip_non_tags: true
image: Visual Studio 2017
cache:
- '%USERPROFILE%\.nuget\packages -> **\*.csproj'
install:
- git clone https://github.com/ppy/osu-deploy
before_build:
@@ -16,7 +18,7 @@ build_script:
- cd osu-deploy
- nuget restore -verbosity quiet
- msbuild osu.Desktop.Deploy.csproj
- cmd: ..\appveyor-tools\secure-file -decrypt ..\fdc6f19b04.enc -secret %decode_secret% -out bin\Debug\net471\osu.Desktop.Deploy.exe.config
- cmd: ..\appveyor-tools\secure-file -decrypt ..\fdc6f19b04.enc -secret %decode_secret% -out bin\Debug\net471\osu-deploy.exe.config
- cd bin\Debug\net471\
- osu.Desktop.Deploy.exe %code_signing_password% %APPVEYOR_REPO_TAG_NAME%
environment:
Submodule
+1
Submodule osu-framework added at b963ce8250
+2 -2
View File
@@ -3,6 +3,7 @@
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Development;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@@ -13,7 +14,6 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Utils;
using OpenTK;
using OpenTK.Graphics;
@@ -118,7 +118,7 @@ namespace osu.Desktop.Overlays
Icon = FontAwesome.fa_check_square;
Activated = delegate
{
Process.Start($"https://osu.ppy.sh/home/changelog/{version}");
Process.Start($"https://github.com/ppy/osu/releases/tag/v{version}");
return true;
};
}
+3 -2
View File
@@ -20,16 +20,17 @@
<StartupObject>osu.Desktop.Program</StartupObject>
</PropertyGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" />
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.3" />
<PackageReference Include="squirrel.windows" Version="1.8.0" Condition="'$(TargetFramework)' == 'net471'" />
</ItemGroup>
<ItemGroup Label="Resources">
@@ -53,10 +53,10 @@ namespace osu.Game.Rulesets.Catch.Tests
return beatmap;
}
protected override Player CreatePlayer(Ruleset ruleset)
protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset)
{
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
return base.CreatePlayer(ruleset);
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
return base.CreatePlayer(beatmap, ruleset);
}
}
}
@@ -98,12 +98,17 @@ namespace osu.Game.Rulesets.Mania.Tests
});
}
private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets, SettingsStore settings)
{
maniaRuleset = rulesets.GetRuleset(3);
Dependencies.Cache(new ManiaConfigManager(settings, maniaRuleset, 4));
dependencies.Cache(new ManiaConfigManager(settings, maniaRuleset, 4));
}
private ManiaPlayfield createPlayfield(int cols, bool inverted = false)
@@ -5,7 +5,6 @@ using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Objects.Drawables;
using OpenTK.Graphics;
namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
@@ -29,7 +28,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
: base(barLine)
{
RelativeSizeAxes = Axes.X;
Height = 2f;
Height = 1;
AddInternal(new Box
{
@@ -37,7 +36,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.Both,
Colour = new Color4(255, 204, 33, 255),
});
bool isMajor = barLine.BeatIndex % (int)barLine.ControlPoint.TimeSignature == 0;
@@ -2,7 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
using OpenTK.Graphics;
@@ -23,7 +23,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
private readonly DrawableNote head;
private readonly DrawableNote tail;
private readonly GlowPiece glowPiece;
private readonly BodyPiece bodyPiece;
private readonly Container fullHeightContainer;
/// <summary>
/// Time at which the user started holding this hold note. Null if the user is not holding this hold note.
@@ -35,17 +37,25 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
/// </summary>
private bool hasBroken;
private readonly Container<DrawableHoldNoteTick> tickContainer;
public DrawableHoldNote(HoldNote hitObject, ManiaAction action)
: base(hitObject, action)
{
Container<DrawableHoldNoteTick> tickContainer;
RelativeSizeAxes = Axes.X;
InternalChildren = new Drawable[]
{
// The hit object itself cannot be used for various elements because the tail overshoots it
// So a specialized container that is updated to contain the tail height is used
fullHeightContainer = new Container
{
RelativeSizeAxes = Axes.X,
Child = glowPiece = new GlowPiece()
},
bodyPiece = new BodyPiece
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
},
tickContainer = new Container<DrawableHoldNoteTick>
@@ -82,10 +92,21 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
base.AccentColour = value;
glowPiece.AccentColour = value;
bodyPiece.AccentColour = value;
head.AccentColour = value;
tail.AccentColour = value;
tickContainer.ForEach(t => t.AccentColour = value);
}
}
protected override void UpdateState(ArmedState state)
{
switch (state)
{
case ArmedState.Hit:
// Good enough for now, we just want them to have a lifetime end
this.Delay(2000).Expire();
break;
}
}
@@ -100,8 +121,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
base.Update();
// Make the body piece not lie under the head note
bodyPiece.Y = head.Height / 2;
bodyPiece.Height = DrawHeight - head.Height / 2 + tail.Height / 2;
bodyPiece.Y = head.Height;
bodyPiece.Height = DrawHeight - head.Height;
// Make the fullHeightContainer "contain" the height of the tail note, keeping in mind
// that the tail note overshoots the height of this hit object
fullHeightContainer.Height = DrawHeight + tail.Height;
}
public bool OnPressed(ManiaAction action)
@@ -150,6 +175,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
: base(holdNote.HitObject.Head, action)
{
this.holdNote = holdNote;
GlowPiece.Alpha = 0;
}
public override bool OnPressed(ManiaAction action)
@@ -167,6 +194,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
return true;
}
protected override void UpdateState(ArmedState state)
{
// The holdnote keeps scrolling through for now, so having the head disappear looks weird
}
}
/// <summary>
@@ -187,6 +219,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
: base(holdNote.HitObject.Tail, action)
{
this.holdNote = holdNote;
GlowPiece.Alpha = 0;
}
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
@@ -219,6 +253,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
});
}
protected override void UpdateState(ArmedState state)
{
// The holdnote keeps scrolling through, so having the tail disappear looks weird
}
public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down
public override bool OnReleased(ManiaAction action)
@@ -8,6 +8,7 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Scoring;
@@ -86,6 +87,16 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
AddJudgement(new HoldNoteTickJudgement { Result = HitResult.Perfect });
}
protected override void UpdateState(ArmedState state)
{
switch (State.Value)
{
case ArmedState.Hit:
AccentColour = Color4.Green;
break;
}
}
protected override void Update()
{
if (AllJudged)
@@ -27,18 +27,5 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
if (action != null)
Action = action.Value;
}
protected override void UpdateState(ArmedState state)
{
switch (state)
{
case ArmedState.Miss:
this.FadeOut(150, Easing.In).Expire();
break;
case ArmedState.Hit:
this.FadeOut(150, Easing.OutQuint).Expire();
break;
}
}
}
}
@@ -1,13 +1,12 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Extensions.Color4Extensions;
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Mania.Objects.Drawables
@@ -17,6 +16,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
/// </summary>
public class DrawableNote : DrawableManiaHitObject<Note>, IKeyBindingHandler<ManiaAction>
{
protected readonly GlowPiece GlowPiece;
private readonly LaneGlowPiece laneGlowPiece;
private readonly NotePiece headPiece;
public DrawableNote(Note hitObject, ManiaAction action)
@@ -25,11 +27,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
CornerRadius = 5;
Masking = true;
InternalChildren = new Drawable[]
{
laneGlowPiece = new LaneGlowPiece
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
},
GlowPiece = new GlowPiece(),
headPiece = new NotePiece
{
Anchor = Anchor.TopCentre,
@@ -44,14 +49,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
set
{
base.AccentColour = value;
laneGlowPiece.AccentColour = AccentColour;
GlowPiece.AccentColour = AccentColour;
headPiece.AccentColour = AccentColour;
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = AccentColour.Lighten(1f).Opacity(0.6f),
Radius = 10,
};
}
}
@@ -71,6 +71,17 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
AddJudgement(new ManiaJudgement { Result = result });
}
protected override void UpdateState(ArmedState state)
{
switch (state)
{
case ArmedState.Hit:
case ArmedState.Miss:
this.FadeOut(100).Expire();
break;
}
}
public virtual bool OnPressed(ManiaAction action)
{
if (action != Action)
@@ -123,8 +123,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
if (!IsLoaded)
return;
foreground.Colour = AccentColour.Opacity(0.9f);
background.Colour = AccentColour.Opacity(0.6f);
foreground.Colour = AccentColour.Opacity(0.4f);
background.Colour = AccentColour.Opacity(0.2f);
subtractionCache.Invalidate();
}
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
/// </summary>
internal class NotePiece : Container, IHasAccentColour
{
public const float NOTE_HEIGHT = 10;
private const float head_height = 10;
private const float head_colour_height = 6;
private readonly Box colouredBox;
@@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
public NotePiece()
{
RelativeSizeAxes = Axes.X;
Height = NOTE_HEIGHT;
Height = head_height;
Children = new[]
{
+8 -20
View File
@@ -33,7 +33,6 @@ namespace osu.Game.Rulesets.Mania.UI
public ManiaAction Action;
private readonly Box background;
private readonly Box backgroundOverlay;
private readonly Container hitTargetBar;
private readonly Container keyIcon;
@@ -43,32 +42,22 @@ namespace osu.Game.Rulesets.Mania.UI
protected override Container<Drawable> Content => content;
private readonly Container<Drawable> content;
private const float opacity_released = 0.1f;
private const float opacity_pressed = 0.25f;
public Column()
: base(ScrollingDirection.Up)
{
RelativeSizeAxes = Axes.Y;
Width = column_width;
Masking = true;
CornerRadius = 5;
InternalChildren = new Drawable[]
{
background = new Box
{
Name = "Background",
RelativeSizeAxes = Axes.Both,
Alpha = 0.3f
},
backgroundOverlay = new Box
{
Name = "Background Gradient Overlay",
RelativeSizeAxes = Axes.Both,
Height = 0.5f,
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft,
Blending = BlendingMode.Additive,
Alpha = 0
Alpha = opacity_released
},
new Container
{
@@ -193,7 +182,6 @@ namespace osu.Game.Rulesets.Mania.UI
accentColour = value;
background.Colour = accentColour;
backgroundOverlay.Colour = ColourInfo.GradientVertical(accentColour.Opacity(0.6f), accentColour.Opacity(0));
hitTargetBar.EdgeEffect = new EdgeEffectParameters
{
@@ -235,8 +223,8 @@ namespace osu.Game.Rulesets.Mania.UI
{
if (action == Action)
{
backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint);
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint).Then().ScaleTo(1.3f, 250, Easing.OutQuint);
background.FadeTo(opacity_pressed, 50, Easing.OutQuint);
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint);
}
return false;
@@ -246,8 +234,8 @@ namespace osu.Game.Rulesets.Mania.UI
{
if (action == Action)
{
backgroundOverlay.FadeTo(0, 250, Easing.OutQuint);
keyIcon.ScaleTo(1f, 125, Easing.OutQuint);
background.FadeTo(opacity_released, 800, Easing.OutQuart);
keyIcon.ScaleTo(1f, 400, Easing.OutQuart);
}
return false;
+20 -21
View File
@@ -1,21 +1,19 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.MathUtils;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
using osu.Game.Rulesets.Objects.Drawables;
using OpenTK;
namespace osu.Game.Rulesets.Mania.UI
{
internal class HitExplosion : CompositeDrawable
{
private readonly CircularContainer circle;
private readonly Box inner;
public HitExplosion(DrawableHitObject judgedObject)
{
@@ -24,32 +22,33 @@ namespace osu.Game.Rulesets.Mania.UI
Anchor = Anchor.TopCentre;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.X;
Y = NotePiece.NOTE_HEIGHT / 2;
Height = NotePiece.NOTE_HEIGHT;
RelativeSizeAxes = Axes.Both;
Size = new Vector2(isTick ? 0.5f : 1);
FillMode = FillMode.Fit;
// scale roughly in-line with visual appearance of notes
Scale = new Vector2(isTick ? 0.4f : 0.8f);
Blending = BlendingMode.Additive;
InternalChild = circle = new CircularContainer
Color4 accent = isTick ? Color4.White : judgedObject.AccentColour;
InternalChild = new CircularContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Masking = true,
// we want our size to be very small so the glow dominates it.
Size = new Vector2(0.1f),
BorderThickness = 1,
BorderColour = accent,
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = Interpolation.ValueAt(0.1f, judgedObject.AccentColour, Color4.White, 0, 1),
Radius = 100,
Colour = accent,
Radius = 10,
Hollow = true
},
Child = new Box
Child = inner = new Box
{
Alpha = 0,
RelativeSizeAxes = Axes.Both,
AlwaysPresent = true
Colour = accent,
Alpha = 1,
AlwaysPresent = true,
}
};
}
@@ -58,8 +57,8 @@ namespace osu.Game.Rulesets.Mania.UI
{
base.LoadComplete();
circle.ResizeTo(circle.Size * new Vector2(4, 20), 1000, Easing.OutQuint);
this.FadeIn(16).Then().FadeOut(500, Easing.OutQuint);
this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500);
inner.FadeOut(250);
Expire(true);
}
+5 -5
View File
@@ -9,6 +9,7 @@ using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
@@ -77,7 +78,6 @@ namespace osu.Game.Rulesets.Mania.UI
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
Masking = true,
CornerRadius = 5,
Children = new Drawable[]
{
new Box
@@ -183,15 +183,15 @@ namespace osu.Game.Rulesets.Mania.UI
}
[BackgroundDependencyLoader]
private void load()
private void load(OsuColour colours)
{
normalColumnColours = new List<Color4>
{
new Color4(94, 0, 57, 255),
new Color4(6, 84, 0, 255)
colours.RedDark,
colours.GreenDark
};
specialColumnColour = new Color4(0, 48, 63, 255);
specialColumnColour = colours.BlueDark;
// Set the special column + colour + key
foreach (var column in Columns)
+10 -11
View File
@@ -7,34 +7,33 @@ using System.Linq;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModHidden : ModHidden
public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects
{
public override string Description => @"Play with no approach circles and fading circles/sliders.";
public override double ScoreMultiplier => 1.06;
private const double fade_in_duration_multiplier = 0.4;
private const double fade_out_duration_multiplier = 0.3;
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
{
void adjustFadeIn(OsuHitObject h) => h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier;
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
{
adjustFadeIn(d.HitObject);
foreach (var h in d.HitObject.NestedHitObjects.OfType<OsuHitObject>())
adjustFadeIn(h);
}
d.ApplyCustomUpdateState += ApplyHiddenState;
base.ApplyToDrawableHitObjects(drawables);
d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier;
foreach (var h in d.HitObject.NestedHitObjects.OfType<OsuHitObject>())
h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier;
}
}
protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
{
if (!(drawable is DrawableOsuHitObject d))
return;
@@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
private Bindable<double> cursorScale;
private Bindable<bool> autoCursorScale;
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
private Bindable<WorkingBeatmap> beatmap;
public OsuCursor()
{
@@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, IBindableBeatmap beatmap)
private void load(OsuConfigManager config, OsuGameBase game)
{
Child = cursorContainer = new SkinnableDrawable("cursor", _ => new CircularContainer
{
@@ -160,7 +160,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
RelativeSizeAxes = Axes.Both,
};
this.beatmap.BindTo(beatmap);
beatmap = game.Beatmap.GetBoundCopy();
beatmap.ValueChanged += v => calculateScale();
cursorScale = config.GetBindable<double>(OsuSetting.GameplayCursorSize);
@@ -264,8 +264,7 @@ namespace osu.Game.Tests.Beatmaps.IO
private string createTemporaryBeatmap()
{
var temp = Path.GetTempFileName() + ".osz";
File.Copy(osz_path, temp, true);
var temp = new FileInfo(osz_path).CopyTo(Path.GetTempFileName(), true).FullName;
Assert.IsTrue(File.Exists(temp));
return temp;
}
@@ -345,12 +344,12 @@ namespace osu.Game.Tests.Beatmaps.IO
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
{
Task task = Task.Run(() =>
Action waitAction = () =>
{
while (!result()) Thread.Sleep(200);
});
};
Assert.IsTrue(task.Wait(timeout), failureMessage);
Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), failureMessage);
}
}
}
@@ -58,7 +58,7 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile);
Assert.AreEqual("Deif", meta.AuthorString);
Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile);
Assert.AreEqual(164471, meta.PreviewTime);
Assert.AreEqual(164471 + LegacyBeatmapDecoder.UniversalOffset, meta.PreviewTime);
Assert.AreEqual(string.Empty, meta.Source);
Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags);
Assert.AreEqual("Renatus", meta.Title);
+4 -2
View File
@@ -3,6 +3,7 @@
using System.ComponentModel;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play;
@@ -12,11 +13,12 @@ namespace osu.Game.Tests.Visual
[Description("Player instantiated with an autoplay mod.")]
public class TestCaseAutoplay : TestCasePlayer
{
protected override Player CreatePlayer(Ruleset ruleset)
protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset)
{
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
return new ScoreAccessiblePlayer
{
InitialBeatmap = beatmap,
AllowPause = false,
AllowLeadIn = false,
AllowResults = false,
@@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
@@ -28,11 +29,14 @@ namespace osu.Game.Tests.Visual
private RulesetStore rulesets;
private TestBeatmapInfoWedge infoWedge;
private readonly List<IBeatmap> beatmaps = new List<IBeatmap>();
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
private void load(OsuGameBase game, RulesetStore rulesets)
{
this.rulesets = rulesets;
beatmap.BindTo(game.Beatmap);
}
protected override void LoadComplete()
@@ -49,11 +53,11 @@ namespace osu.Game.Tests.Visual
AddStep("show", () =>
{
infoWedge.State = Visibility.Visible;
infoWedge.Beatmap = Beatmap;
infoWedge.Beatmap = beatmap;
});
// select part is redundant, but wait for load isn't
selectBeatmap(Beatmap.Value.Beatmap);
selectBeatmap(beatmap.Value.Beatmap);
AddWaitStep(3);
@@ -116,8 +120,8 @@ namespace osu.Game.Tests.Visual
{
selectNullBeatmap();
AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Text));
AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Title);
AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Artist);
AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Title);
AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Artist);
AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any());
AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any());
}
@@ -129,7 +133,7 @@ namespace osu.Game.Tests.Visual
AddStep($"select {b.Metadata.Title} beatmap", () =>
{
infoBefore = infoWedge.Info;
infoWedge.Beatmap = Beatmap.Value = new TestWorkingBeatmap(b);
infoWedge.Beatmap = beatmap.Value = new TestWorkingBeatmap(b);
});
AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load");
@@ -139,8 +143,8 @@ namespace osu.Game.Tests.Visual
{
AddStep("select null beatmap", () =>
{
Beatmap.Value = Beatmap.Default;
infoWedge.Beatmap = Beatmap;
beatmap.Value = beatmap.Default;
infoWedge.Beatmap = beatmap;
});
}
+4 -1
View File
@@ -35,6 +35,9 @@ namespace osu.Game.Tests.Visual
typeof(MessageFormatter)
};
private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
public TestCaseChatLink()
{
Add(textContainer = new TestChatLineContainer
@@ -50,7 +53,7 @@ namespace osu.Game.Tests.Visual
private void load(OsuColour colours)
{
linkColour = colours.Blue;
Dependencies.Cache(new ChatOverlay
dependencies.Cache(new ChatOverlay
{
AvailableChannels =
{
@@ -17,10 +17,14 @@ namespace osu.Game.Tests.Visual
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(Compose) };
[BackgroundDependencyLoader]
private void load()
private void load(OsuGameBase osuGame)
{
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
Child = new Compose();
osuGame.Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
var compose = new Compose();
compose.Beatmap.BindTo(osuGame.Beatmap);
Child = compose;
}
}
}
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using NUnit.Framework;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Overlays;
@@ -17,6 +18,8 @@ namespace osu.Game.Tests.Visual
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) };
private readonly ScrollableTimeline timeline;
public TestCaseEditorComposeTimeline()
{
Children = new Drawable[]
@@ -27,7 +30,7 @@ namespace osu.Game.Tests.Visual
Origin = Anchor.TopCentre,
State = Visibility.Visible
},
new ScrollableTimeline
timeline = new ScrollableTimeline
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -35,5 +38,11 @@ namespace osu.Game.Tests.Visual
}
};
}
[BackgroundDependencyLoader]
private void load(OsuGameBase osuGame)
{
timeline.Beatmap.BindTo(osuGame.Beatmap);
}
}
}
@@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual
}
[BackgroundDependencyLoader]
private void load()
private void load(OsuGameBase osuGame)
{
var testBeatmap = new Beatmap
{
@@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual
}
};
Beatmap.Value = new TestWorkingBeatmap(testBeatmap);
osuGame.Beatmap.Value = new TestWorkingBeatmap(testBeatmap);
Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock };
@@ -19,16 +19,19 @@ namespace osu.Game.Tests.Visual
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(SummaryTimeline) };
[BackgroundDependencyLoader]
private void load()
private void load(OsuGameBase osuGame)
{
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
osuGame.Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
Add(new SummaryTimeline
SummaryTimeline summaryTimeline;
Add(summaryTimeline = new SummaryTimeline
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(500, 50)
});
summaryTimeline.Beatmap.BindTo(osuGame.Beatmap);
}
}
}
@@ -32,10 +32,15 @@ namespace osu.Game.Tests.Visual
typeof(NotNullAttribute)
};
private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
=> dependencies = new DependencyContainer(parent);
[BackgroundDependencyLoader]
private void load()
private void load(OsuGameBase osuGame)
{
Beatmap.Value = new TestWorkingBeatmap(new Beatmap
osuGame.Beatmap.Value = new TestWorkingBeatmap(new Beatmap
{
HitObjects = new List<HitObject>
{
@@ -58,8 +63,8 @@ namespace osu.Game.Tests.Visual
});
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
Dependencies.CacheAs<IAdjustableClock>(clock);
Dependencies.CacheAs<IFrameBasedClock>(clock);
dependencies.CacheAs<IAdjustableClock>(clock);
dependencies.CacheAs<IFrameBasedClock>(clock);
Child = new OsuHitObjectComposer(new OsuRuleset());
}
@@ -2,9 +2,12 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Overlays;
namespace osu.Game.Tests.Visual
@@ -12,6 +15,8 @@ namespace osu.Game.Tests.Visual
[TestFixture]
public class TestCaseMusicController : OsuTestCase
{
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
public TestCaseMusicController()
{
Clock = new FramedClock();
@@ -25,7 +30,13 @@ namespace osu.Game.Tests.Visual
AddToggleStep(@"toggle visibility", state => mc.State = state ? Visibility.Visible : Visibility.Hidden);
AddStep(@"show", () => mc.State = Visibility.Visible);
AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state);
AddToggleStep(@"toggle beatmap lock", state => beatmapBacking.Disabled = state);
}
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
{
beatmapBacking.BindTo(game.Beatmap);
}
}
}
@@ -27,6 +27,7 @@ namespace osu.Game.Tests.Visual
private RulesetStore rulesets;
private DependencyContainer dependencies;
private WorkingBeatmap defaultBeatmap;
public override IReadOnlyList<Type> RequiredTypes => new[]
@@ -47,6 +48,8 @@ namespace osu.Game.Tests.Visual
typeof(DrawableCarouselBeatmapSet),
};
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
private class TestSongSelect : PlaySongSelect
{
public WorkingBeatmap CurrentBeatmap => Beatmap.Value;
@@ -55,7 +58,7 @@ namespace osu.Game.Tests.Visual
}
[BackgroundDependencyLoader]
private void load()
private void load(OsuGameBase game)
{
TestSongSelect songSelect = null;
@@ -64,10 +67,10 @@ namespace osu.Game.Tests.Visual
// this is by no means clean. should be replacing inside of OsuGameBase somehow.
IDatabaseContextFactory factory = new SingletonContextFactory(new OsuDbContext());
Dependencies.Cache(rulesets = new RulesetStore(factory));
Dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null, null)
dependencies.Cache(rulesets = new RulesetStore(factory));
dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null, null)
{
DefaultBeatmap = defaultBeatmap = Beatmap.Default
DefaultBeatmap = defaultBeatmap = game.Beatmap.Default
});
void loadNewSongSelect(bool deleteMaps = false) => AddStep("reload song select", () =>
@@ -75,7 +78,7 @@ namespace osu.Game.Tests.Visual
if (deleteMaps)
{
manager.Delete(manager.GetAllUsableBeatmapSets());
Beatmap.SetDefault();
game.Beatmap.SetDefault();
}
if (songSelect != null)
@@ -15,12 +15,17 @@ namespace osu.Game.Tests.Visual
[TestFixture]
public class TestCasePlaybackControl : OsuTestCase
{
private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
=> dependencies = new DependencyContainer(parent);
[BackgroundDependencyLoader]
private void load()
{
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
Dependencies.CacheAs<IAdjustableClock>(clock);
Dependencies.CacheAs<IFrameBasedClock>(clock);
dependencies.CacheAs<IAdjustableClock>(clock);
dependencies.CacheAs<IFrameBasedClock>(clock);
var playback = new PlaybackControl
{
@@ -29,7 +34,7 @@ namespace osu.Game.Tests.Visual
Size = new Vector2(200,100)
};
Beatmap.Value = new TestWorkingBeatmap(new Beatmap());
playback.Beatmap.Value = new TestWorkingBeatmap(new Beatmap());
Child = playback;
}
@@ -12,10 +12,9 @@ namespace osu.Game.Tests.Visual
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
{
Beatmap.Value = new DummyWorkingBeatmap(game);
AddStep("load dummy beatmap", () => Add(new PlayerLoader(new Player
{
InitialBeatmap = new DummyWorkingBeatmap(game),
AllowPause = false,
AllowLeadIn = false,
AllowResults = false,
+9 -5
View File
@@ -3,6 +3,7 @@
using System.ComponentModel;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play;
@@ -12,20 +13,23 @@ namespace osu.Game.Tests.Visual
[Description("Player instantiated with a replay.")]
public class TestCaseReplay : TestCasePlayer
{
protected override Player CreatePlayer(Ruleset ruleset)
protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset)
{
// We create a dummy RulesetContainer just to get the replay - we don't want to use mods here
// to simulate setting a replay rather than having the replay already set for us
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(Beatmap.Value);
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(beatmap);
// We have the replay
var replay = dummyRulesetContainer.Replay;
// Reset the mods
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay));
beatmap.Mods.Value = beatmap.Mods.Value.Where(m => !(m is ModAutoplay));
return new ReplayPlayer(replay);
return new ReplayPlayer(replay)
{
InitialBeatmap = beatmap
};
}
}
}
+12 -4
View File
@@ -32,13 +32,18 @@ namespace osu.Game.Tests.Visual
this.beatmaps = beatmaps;
}
private WorkingBeatmap beatmap;
protected override void LoadComplete()
{
base.LoadComplete();
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
if (beatmapInfo != null)
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
if (beatmap == null)
{
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
if (beatmapInfo != null)
beatmap = beatmaps.GetWorkingBeatmap(beatmapInfo);
}
Add(new Results(new Score
{
@@ -58,7 +63,10 @@ namespace osu.Game.Tests.Visual
{
Username = "peppy",
}
}));
})
{
InitialBeatmap = beatmap
});
}
}
}
+5 -1
View File
@@ -14,6 +14,10 @@ namespace osu.Game.Tests.Visual
private readonly SettingsOverlay settings;
private readonly DialogOverlay dialogOverlay;
private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
public TestCaseSettings()
{
settings = new MainSettings
@@ -29,7 +33,7 @@ namespace osu.Game.Tests.Visual
[BackgroundDependencyLoader]
private void load()
{
Dependencies.Cache(dialogOverlay);
dependencies.Cache(dialogOverlay);
Add(settings);
}
+9 -6
View File
@@ -3,6 +3,7 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@@ -17,6 +18,8 @@ namespace osu.Game.Tests.Visual
[TestFixture]
public class TestCaseStoryboard : OsuTestCase
{
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
private readonly Container<DrawableStoryboard> storyboardContainer;
private DrawableStoryboard storyboard;
@@ -40,7 +43,6 @@ namespace osu.Game.Tests.Visual
},
},
});
Add(new MusicController
{
Origin = Anchor.TopRight,
@@ -53,9 +55,10 @@ namespace osu.Game.Tests.Visual
}
[BackgroundDependencyLoader]
private void load()
private void load(OsuGameBase game)
{
Beatmap.ValueChanged += beatmapChanged;
beatmapBacking.BindTo(game.Beatmap);
beatmapBacking.ValueChanged += beatmapChanged;
}
private void beatmapChanged(WorkingBeatmap working)
@@ -63,10 +66,10 @@ namespace osu.Game.Tests.Visual
private void restart()
{
var track = Beatmap.Value.Track;
var track = beatmapBacking.Value.Track;
track.Reset();
loadStoryboard(Beatmap);
loadStoryboard(beatmapBacking.Value);
track.Start();
}
@@ -78,7 +81,7 @@ namespace osu.Game.Tests.Visual
var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true };
storyboardContainer.Clock = decoupledClock;
storyboard = working.Storyboard.CreateDrawable(Beatmap);
storyboard = working.Storyboard.CreateDrawable(beatmapBacking);
storyboard.Passing = false;
storyboardContainer.Add(storyboard);
+10 -5
View File
@@ -5,9 +5,11 @@ using NUnit.Framework;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
@@ -17,8 +19,9 @@ namespace osu.Game.Tests.Visual
[TestFixture]
public class TestCaseWaveform : OsuTestCase
{
[BackgroundDependencyLoader]
private void load()
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
public TestCaseWaveform()
{
FillFlowContainer flow;
Child = flow = new FillFlowContainer
@@ -43,11 +46,10 @@ namespace osu.Game.Tests.Visual
var newDisplay = new BeatmapWaveformGraph
{
RelativeSizeAxes = Axes.Both,
Resolution = 1f / i,
Beatmap = Beatmap
Resolution = 1f / i
};
Beatmap.ValueChanged += b => newDisplay.Beatmap = b;
newDisplay.Beatmap.BindTo(beatmapBacking);
flow.Add(new Container
{
@@ -81,5 +83,8 @@ namespace osu.Game.Tests.Visual
});
}
}
[BackgroundDependencyLoader]
private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap);
}
}
-75
View File
@@ -1,75 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Diagnostics;
using JetBrains.Annotations;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Configuration;
namespace osu.Game.Beatmaps
{
/// <summary>
/// A <see cref="Bindable{WorkingBeatmap}"/> for the <see cref="OsuGame"/> beatmap.
/// This should be used sparingly in-favour of <see cref="IBindableBeatmap"/>.
/// </summary>
public abstract class BindableBeatmap : NonNullableBindable<WorkingBeatmap>, IBindableBeatmap
{
private AudioManager audioManager;
private WorkingBeatmap lastBeatmap;
protected BindableBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue)
{
}
/// <summary>
/// Registers an <see cref="AudioManager"/> for <see cref="Track"/>s to be added to.
/// </summary>
/// <param name="audioManager">The <see cref="AudioManager"/> to register.</param>
protected void RegisterAudioManager([NotNull] AudioManager audioManager)
{
if (this.audioManager != null) throw new InvalidOperationException($"Cannot register multiple {nameof(AudioManager)}s.");
this.audioManager = audioManager;
ValueChanged += registerAudioTrack;
// If the track has changed prior to this being called, let's register it
if (Value != Default)
registerAudioTrack(Value);
}
private void registerAudioTrack(WorkingBeatmap beatmap)
{
var trackLoaded = lastBeatmap?.TrackLoaded ?? false;
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
if (!trackLoaded || lastBeatmap?.Track != beatmap.Track)
{
if (trackLoaded)
{
Debug.Assert(lastBeatmap != null);
Debug.Assert(lastBeatmap.Track != null);
lastBeatmap.RecycleTrack();
}
audioManager.Track.AddItem(beatmap.Track);
}
lastBeatmap = beatmap;
}
[NotNull]
IBindableBeatmap IBindableBeatmap.GetBoundCopy() => GetBoundCopy();
/// <summary>
/// Retrieve a new <see cref="BindableBeatmap"/> instance weakly bound to this <see cref="BindableBeatmap"/>.
/// If you are further binding to events of the retrieved <see cref="BindableBeatmap"/>, ensure a local reference is held.
/// </summary>
[NotNull]
public abstract BindableBeatmap GetBoundCopy();
}
}
@@ -1,84 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
namespace osu.Game.Beatmaps.Drawables
{
/// <summary>
/// A component to allow downloading of a beatmap set. Automatically handles state syncing between other instances.
/// </summary>
public class BeatmapSetDownloader : Component
{
private readonly BeatmapSetInfo set;
private readonly bool noVideo;
private BeatmapManager beatmaps;
/// <summary>
/// Whether the associated beatmap set has been downloading (by this instance or any other instance).
/// </summary>
public readonly BindableBool Downloaded = new BindableBool();
public BeatmapSetDownloader(BeatmapSetInfo set, bool noVideo = false)
{
this.set = set;
this.noVideo = noVideo;
}
[BackgroundDependencyLoader]
private void load(BeatmapManager beatmaps)
{
this.beatmaps = beatmaps;
beatmaps.ItemAdded += setAdded;
beatmaps.ItemRemoved += setRemoved;
// initial value
if (set.OnlineBeatmapSetID != null)
Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Any();
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (beatmaps != null)
{
beatmaps.ItemAdded -= setAdded;
beatmaps.ItemRemoved -= setRemoved;
}
}
/// <summary>
/// Begin downloading the associated beatmap set.
/// </summary>
/// <returns>True if downloading began. False if an existing download is active or completed.</returns>
public bool Download()
{
if (Downloaded.Value)
return false;
if (beatmaps.GetExistingDownload(set) != null)
return false;
beatmaps.Download(set, noVideo);
return true;
}
private void setAdded(BeatmapSetInfo s)
{
if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
Downloaded.Value = true;
}
private void setRemoved(BeatmapSetInfo s)
{
if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
Downloaded.Value = false;
}
}
}
+2 -2
View File
@@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps
{
private readonly OsuGameBase game;
public DummyWorkingBeatmap(OsuGameBase game = null)
public DummyWorkingBeatmap(OsuGameBase game)
: base(new BeatmapInfo
{
Metadata = new BeatmapMetadata
@@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps
protected override IBeatmap GetBeatmap() => new Beatmap();
protected override Texture GetBackground() => game?.Textures.Get(@"Backgrounds/bg4");
protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4");
protected override Track GetTrack() => new TrackVirtual();
@@ -8,6 +8,7 @@ using System.Linq;
using osu.Game.Beatmaps.Timing;
using osu.Game.Rulesets.Objects.Legacy;
using osu.Game.Beatmaps.ControlPoints;
using osu.Framework;
namespace osu.Game.Beatmaps.Formats
{
@@ -27,17 +28,23 @@ namespace osu.Game.Beatmaps.Formats
AddDecoder<Beatmap>(@"osu file format v", m => new LegacyBeatmapDecoder(int.Parse(m.Split('v').Last())));
}
/// <summary>
/// lazer's audio timings in general doesn't match stable. this is the result of user testing, albeit limited.
/// This only seems to be required on windows. We need to eventually figure out why, with a bit of luck.
/// </summary>
public static int UniversalOffset => RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? -22 : 0;
/// <summary>
/// Whether or not beatmap or runtime offsets should be applied. Defaults on; only disable for testing purposes.
/// </summary>
public bool ApplyOffsets = true;
private readonly int offset;
private readonly int offset = UniversalOffset;
public LegacyBeatmapDecoder(int version = LATEST_VERSION) : base(version)
{
// BeatmapVersion 4 and lower had an incorrect offset (stable has this set as 24ms off)
offset = FormatVersion < 5 ? 24 : 0;
offset += FormatVersion < 5 ? 24 : 0;
}
protected override void ParseStreamInto(StreamReader stream, Beatmap beatmap)
-19
View File
@@ -1,19 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Configuration;
namespace osu.Game.Beatmaps
{
/// <summary>
/// Read-only interface for the <see cref="OsuGame"/> beatmap.
/// </summary>
public interface IBindableBeatmap : IBindable<WorkingBeatmap>
{
/// <summary>
/// Retrieve a new <see cref="IBindableBeatmap"/> instance weakly bound to this <see cref="IBindableBeatmap"/>.
/// If you are further binding to events of the retrieved <see cref="IBindableBeatmap"/>, ensure a local reference is held.
/// </summary>
IBindableBeatmap GetBoundCopy();
}
}
+1 -4
View File
@@ -82,8 +82,6 @@ namespace osu.Game.Configuration
Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential);
Set(OsuSetting.IncreaseFirstObjectVisibility, true);
// Update
Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer);
@@ -146,7 +144,6 @@ namespace osu.Game.Configuration
ScreenshotCaptureMenuCursor,
SongSelectRightMouseScroll,
BeatmapSkins,
BeatmapHitsounds,
IncreaseFirstObjectVisibility
BeatmapHitsounds
}
}
+1 -2
View File
@@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using osu.Framework.IO.File;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Game.IO;
@@ -365,7 +364,7 @@ namespace osu.Game.Database
using (Stream s = reader.GetStream(file))
fileInfos.Add(new TFileModel
{
Filename = FileSafety.PathSanitise(file),
Filename = file,
FileInfo = files.Add(s)
});
+13 -29
View File
@@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
using System.Threading;
using Microsoft.EntityFrameworkCore.Storage;
@@ -47,36 +46,20 @@ namespace osu.Game.Database
public DatabaseWriteUsage GetForWrite(bool withTransaction = true)
{
Monitor.Enter(writeLock);
OsuDbContext context;
try
if (currentWriteTransaction == null && withTransaction)
{
if (currentWriteTransaction == null && withTransaction)
{
// this mitigates the fact that changes on tracked entities will not be rolled back with the transaction by ensuring write operations are always executed in isolated contexts.
// if this results in sub-optimal efficiency, we may need to look into removing Database-level transactions in favour of running SaveChanges where we currently commit the transaction.
if (threadContexts.IsValueCreated)
recycleThreadContexts();
// this mitigates the fact that changes on tracked entities will not be rolled back with the transaction by ensuring write operations are always executed in isolated contexts.
// if this results in sub-optimal efficiency, we may need to look into removing Database-level transactions in favour of running SaveChanges where we currently commit the transaction.
if (threadContexts.IsValueCreated)
recycleThreadContexts();
context = threadContexts.Value;
currentWriteTransaction = context.Database.BeginTransaction();
}
else
{
// we want to try-catch the retrieval of the context because it could throw an error (in CreateContext).
context = threadContexts.Value;
}
}
catch (Exception e)
{
// retrieval of a context could trigger a fatal error.
Monitor.Exit(writeLock);
throw;
currentWriteTransaction = threadContexts.Value.Database.BeginTransaction();
}
Interlocked.Increment(ref currentWriteUsages);
return new DatabaseWriteUsage(context, usageCompleted) { IsTransactionLeader = currentWriteTransaction != null && currentWriteUsages == 1 };
return new DatabaseWriteUsage(threadContexts.Value, usageCompleted) { IsTransactionLeader = currentWriteTransaction != null && currentWriteUsages == 1 };
}
private void usageCompleted(DatabaseWriteUsage usage)
@@ -117,18 +100,19 @@ namespace osu.Game.Database
private void recycleThreadContexts() => threadContexts = new ThreadLocal<OsuDbContext>(CreateContext);
protected virtual OsuDbContext CreateContext() => new OsuDbContext(host.Storage.GetDatabaseConnectionString(database_name))
protected virtual OsuDbContext CreateContext()
{
Database = { AutoTransactionsEnabled = false }
};
var ctx = new OsuDbContext(host.Storage.GetDatabaseConnectionString(database_name));
ctx.Database.AutoTransactionsEnabled = false;
return ctx;
}
public void ResetDatabase()
{
lock (writeLock)
{
recycleThreadContexts();
GC.Collect();
GC.WaitForPendingFinalizers();
host.Storage.DeleteDatabase(database_name);
}
}
+4 -13
View File
@@ -58,20 +58,11 @@ namespace osu.Game.Database
this.connectionString = connectionString;
var connection = Database.GetDbConnection();
try
connection.Open();
using (var cmd = connection.CreateCommand())
{
connection.Open();
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = "PRAGMA journal_mode=WAL;";
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
connection.Close();
throw;
cmd.CommandText = "PRAGMA journal_mode=WAL;";
cmd.ExecuteNonQuery();
}
}
@@ -12,7 +12,7 @@ namespace osu.Game.Graphics.Containers
{
public class BeatSyncedContainer : Container
{
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
protected readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
private int lastBeat;
private TimingControlPoint lastTimingPoint;
@@ -74,9 +74,9 @@ namespace osu.Game.Graphics.Containers
}
[BackgroundDependencyLoader]
private void load(IBindableBeatmap beatmap)
private void load(OsuGameBase game)
{
Beatmap.BindTo(beatmap);
Beatmap.BindTo(game.Beatmap);
}
protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
@@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using OpenTK;
using osu.Framework.Configuration;
using osu.Game.Overlays;
namespace osu.Game.Graphics.Containers
{
@@ -17,13 +16,13 @@ namespace osu.Game.Graphics.Containers
private SampleChannel samplePopIn;
private SampleChannel samplePopOut;
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
private readonly BindableBool allowOpeningOverlays = new BindableBool(true);
[BackgroundDependencyLoader(true)]
private void load(OsuGame osuGame, AudioManager audio)
{
if (osuGame != null)
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays);
samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in");
samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out");
@@ -53,18 +52,20 @@ namespace osu.Game.Graphics.Containers
private void onStateChanged(Visibility visibility)
{
switch (visibility)
if (allowOpeningOverlays)
{
case Visibility.Visible:
if (OverlayActivationMode != OverlayActivation.Disabled)
switch (visibility)
{
case Visibility.Visible:
samplePopIn?.Play();
else
State = Visibility.Hidden;
break;
case Visibility.Hidden:
samplePopOut?.Play();
break;
break;
case Visibility.Hidden:
samplePopOut?.Play();
break;
}
}
else
State = Visibility.Hidden;
}
}
}
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using osu.Framework.IO.File;
namespace osu.Game.IO.Archives
{
@@ -14,20 +15,19 @@ namespace osu.Game.IO.Archives
{
private readonly string path;
public LegacyFilesystemReader(string path)
: base(Path.GetFileName(path))
public LegacyFilesystemReader(string path) : base(Path.GetFileName(path))
{
// re-get full path to standardise with Directory.GetFiles return values below.
this.path = Path.GetFullPath(path);
this.path = path;
}
public override Stream GetStream(string name) => File.OpenRead(Path.Combine(path, name));
public override void Dispose()
{
// no-op
}
public override IEnumerable<string> Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => f.Replace(path, string.Empty).Trim(Path.DirectorySeparatorChar)).ToArray();
public override IEnumerable<string> Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => FileSafety.GetRelativePath(f, path)).ToArray();
public override Stream GetUnderlyingStream() => null;
}
+28 -26
View File
@@ -77,7 +77,8 @@ namespace osu.Game
public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight;
public readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
public readonly BindableBool HideOverlaysOnEnter = new BindableBool();
public readonly BindableBool AllowOpeningOverlays = new BindableBool(true);
private OsuScreen screenStack;
@@ -93,8 +94,6 @@ namespace osu.Game
private SettingsOverlay settings;
private readonly List<OverlayContainer> overlays = new List<OverlayContainer>();
// todo: move this to SongSelect once Screen has the ability to unsuspend.
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new List<Mod>());
@@ -107,17 +106,6 @@ namespace osu.Game
public void ToggleDirect() => direct.ToggleVisibility();
/// <summary>
/// Close all game-wide overlays.
/// </summary>
/// <param name="toolbar">Whether the toolbar should also be hidden.</param>
public void CloseAllOverlays(bool toolbar = true)
{
foreach (var o in overlays)
o.State = Visibility.Hidden;
if (toolbar) Toolbar.State = Visibility.Hidden;
}
private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
@@ -263,7 +251,7 @@ namespace osu.Game
Depth = -5,
OnHome = delegate
{
CloseAllOverlays(false);
hideAllOverlays();
intro?.ChildScreen?.MakeCurrent();
},
}, overlayContent.Add);
@@ -320,8 +308,6 @@ namespace osu.Game
// ensure only one of these overlays are open at once.
var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct };
overlays.AddRange(singleDisplayOverlays);
foreach (var overlay in singleDisplayOverlays)
{
overlay.StateChanged += state =>
@@ -337,8 +323,6 @@ namespace osu.Game
}
var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications };
overlays.AddRange(singleDisplaySideOverlays);
foreach (var overlay in singleDisplaySideOverlays)
{
overlay.StateChanged += state =>
@@ -355,8 +339,6 @@ namespace osu.Game
// eventually informational overlays should be displayed in a stack, but for now let's only allow one to stay open at a time.
var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile };
overlays.AddRange(informationalOverlays);
foreach (var overlay in informationalOverlays)
{
overlay.StateChanged += state =>
@@ -371,11 +353,6 @@ namespace osu.Game
};
}
OverlayActivationMode.ValueChanged += v =>
{
if (v != OverlayActivation.All) CloseAllOverlays();
};
void updateScreenOffset()
{
float offset = 0;
@@ -390,6 +367,21 @@ namespace osu.Game
settings.StateChanged += _ => updateScreenOffset();
notifications.StateChanged += _ => updateScreenOffset();
notifications.Enabled.BindTo(AllowOpeningOverlays);
HideOverlaysOnEnter.ValueChanged += hide =>
{
//central game screen change logic.
if (hide)
{
hideAllOverlays();
musicController.State = Visibility.Hidden;
Toolbar.State = Visibility.Hidden;
}
else
Toolbar.State = Visibility.Visible;
};
}
private void forwardLoggedErrorsToNotifications()
@@ -506,6 +498,16 @@ namespace osu.Game
private OsuScreen currentScreen;
private FrameworkConfigManager frameworkConfig;
private void hideAllOverlays()
{
settings.State = Visibility.Hidden;
chat.State = Visibility.Hidden;
direct.State = Visibility.Hidden;
social.State = Visibility.Hidden;
userProfile.State = Visibility.Hidden;
notifications.State = Visibility.Hidden;
}
protected override bool OnExiting()
{
if (screenStack.ChildScreen == null) return false;
+49 -52
View File
@@ -3,12 +3,14 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Configuration;
using osu.Framework.Development;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.IO.Stores;
@@ -29,7 +31,6 @@ using osu.Game.IO;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
using DebugUtils = osu.Game.Utils.DebugUtils;
namespace osu.Game
{
@@ -58,12 +59,13 @@ namespace osu.Game
protected MenuCursorContainer MenuCursorContainer;
protected override string MainResourceFile => @"osu.Game.Resources.dll";
private Container content;
protected override Container<Drawable> Content => content;
private OsuBindableBeatmap beatmap;
protected BindableBeatmap Beatmap => beatmap;
public Bindable<WorkingBeatmap> Beatmap { get; private set; }
private Bindable<bool> fpsDisplayVisible;
@@ -98,8 +100,6 @@ namespace osu.Game
[BackgroundDependencyLoader]
private void load()
{
Resources.AddStore(new DllResourceStore(@"osu.Game.Resources.dll"));
dependencies.Cache(contextFactory = new DatabaseContextFactory(Host));
dependencies.Cache(new LargeTextureStore(new RawTextureLoaderStore(new NamespacedResourceStore<byte[]>(Resources, @"Textures"))));
@@ -157,15 +157,33 @@ namespace osu.Game
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light"));
var defaultBeatmap = new DummyWorkingBeatmap(this);
beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio);
Beatmap = new NonNullableBindable<WorkingBeatmap>(defaultBeatmap);
BeatmapManager.DefaultBeatmap = defaultBeatmap;
// tracks play so loud our samples can't keep up.
// this adds a global reduction of track volume for the time being.
Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
dependencies.CacheAs<BindableBeatmap>(beatmap);
dependencies.CacheAs<IBindableBeatmap>(beatmap);
Beatmap.ValueChanged += b =>
{
var trackLoaded = lastBeatmap?.TrackLoaded ?? false;
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
if (!trackLoaded || lastBeatmap?.Track != b.Track)
{
if (trackLoaded)
{
Debug.Assert(lastBeatmap != null);
Debug.Assert(lastBeatmap.Track != null);
lastBeatmap.RecycleTrack();
}
Audio.Track.AddItem(b.Track);
}
lastBeatmap = b;
};
FileStore.Cleanup();
@@ -186,6 +204,29 @@ namespace osu.Game
dependencies.Cache(globalBinding);
}
private void runMigrations()
{
try
{
using (var db = contextFactory.GetForWrite(false))
db.Context.Migrate();
}
catch (MigrationFailedException e)
{
Logger.Error(e.InnerException ?? e, "Migration failed! We'll be starting with a fresh database.", LoggingTarget.Database);
// if we failed, let's delete the database and start fresh.
// todo: we probably want a better (non-destructive) migrations/recovery process at a later point than this.
contextFactory.ResetDatabase();
Logger.Log("Database purged successfully.", LoggingTarget.Database, LogLevel.Important);
using (var db = contextFactory.GetForWrite(false))
db.Context.Migrate();
}
}
private WorkingBeatmap lastBeatmap;
protected override void LoadComplete()
{
base.LoadComplete();
@@ -197,29 +238,6 @@ namespace osu.Game
fpsDisplayVisible.TriggerChange();
}
private void runMigrations()
{
try
{
using (var db = contextFactory.GetForWrite(false))
db.Context.Migrate();
}
catch (Exception e)
{
Logger.Error(e.InnerException ?? e, "Migration failed! We'll be starting with a fresh database.", LoggingTarget.Database);
// if we failed, let's delete the database and start fresh.
// todo: we probably want a better (non-destructive) migrations/recovery process at a later point than this.
contextFactory.ResetDatabase();
Logger.Log("Database purged successfully.", LoggingTarget.Database, LogLevel.Important);
// only run once more, then hard bail.
using (var db = contextFactory.GetForWrite(false))
db.Context.Migrate();
}
}
public override void SetHost(GameHost host)
{
if (LocalConfig == null)
@@ -238,26 +256,5 @@ namespace osu.Game
}
public string[] HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions).ToArray();
private class OsuBindableBeatmap : BindableBeatmap
{
public OsuBindableBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager)
: this(defaultValue)
{
RegisterAudioManager(audioManager);
}
private OsuBindableBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue)
{
}
public override BindableBeatmap GetBoundCopy()
{
var copy = new OsuBindableBeatmap(Default);
copy.BindTo(this);
return copy;
}
}
}
}
@@ -3,8 +3,6 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using OpenTK;
@@ -13,11 +11,10 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
{
public class DownloadButton : HeaderButton
{
public DownloadButton(BeatmapSetInfo set, bool noVideo = false)
public DownloadButton(string title, string subtitle)
{
Width = 120;
BeatmapSetDownloader downloader;
Add(new Container
{
Depth = -1,
@@ -25,7 +22,6 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
Padding = new MarginPadding { Horizontal = 10 },
Children = new Drawable[]
{
downloader = new BeatmapSetDownloader(set, noVideo),
new FillFlowContainer
{
Anchor = Anchor.CentreLeft,
@@ -36,13 +32,13 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
{
new OsuSpriteText
{
Text = "Download",
Text = title,
TextSize = 13,
Font = @"Exo2.0-Bold",
},
new OsuSpriteText
{
Text = set.OnlineInfo.HasVideo && noVideo ? "without Video" : string.Empty,
Text = subtitle,
TextSize = 11,
Font = @"Exo2.0-Bold",
},
@@ -58,25 +54,6 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
},
},
});
Action = () =>
{
if (!downloader.Download())
{
Content.MoveToX(-5, 50, Easing.OutSine).Then()
.MoveToX(5, 100, Easing.InOutSine).Then()
.MoveToX(-5, 100, Easing.InOutSine).Then()
.MoveToX(0, 50, Easing.InSine);
}
};
downloader.Downloaded.ValueChanged += d =>
{
if (d)
this.FadeOut(200);
else
this.FadeIn(200);
};
}
}
}
+51 -19
View File
@@ -35,6 +35,8 @@ namespace osu.Game.Overlays.BeatmapSet
private readonly BeatmapSetOnlineStatusPill onlineStatusPill;
public Details Details;
private BeatmapManager beatmaps;
public readonly BeatmapPicker Picker;
private BeatmapSetInfo beatmapSet;
@@ -66,24 +68,8 @@ namespace osu.Game.Overlays.BeatmapSet
downloadButtonsContainer.FadeIn(transition_duration);
favouriteButton.FadeIn(transition_duration);
if (BeatmapSet.OnlineInfo.HasVideo)
{
videoButtons.Children = new[]
{
new DownloadButton(BeatmapSet),
new DownloadButton(BeatmapSet, true),
};
videoButtons.FadeIn(transition_duration);
noVideoButtons.FadeOut(transition_duration);
}
else
{
noVideoButtons.Child = new DownloadButton(BeatmapSet);
noVideoButtons.FadeIn(transition_duration);
videoButtons.FadeOut(transition_duration);
}
noVideoButtons.FadeTo(BeatmapSet.OnlineInfo.HasVideo ? 0 : 1, transition_duration);
videoButtons.FadeTo(BeatmapSet.OnlineInfo.HasVideo ? 1 : 0, transition_duration);
}
else
{
@@ -206,12 +192,27 @@ namespace osu.Game.Overlays.BeatmapSet
{
RelativeSizeAxes = Axes.Both,
Alpha = 0f,
Child = new DownloadButton("Download", @"")
{
Action = () => download(false),
},
},
videoButtons = new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Spacing = new Vector2(buttons_spacing),
Alpha = 0f,
Children = new[]
{
new DownloadButton("Download", "with Video")
{
Action = () => download(false),
},
new DownloadButton("Download", "without Video")
{
Action = () => download(true),
},
},
},
},
},
@@ -247,10 +248,41 @@ namespace osu.Game.Overlays.BeatmapSet
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, BeatmapManager beatmaps)
{
tabsBg.Colour = colours.Gray3;
this.beatmaps = beatmaps;
beatmaps.ItemAdded += handleBeatmapAdd;
updateDisplay();
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (beatmaps != null) beatmaps.ItemAdded -= handleBeatmapAdd;
}
private void handleBeatmapAdd(BeatmapSetInfo beatmap) => Schedule(() =>
{
if (beatmap.OnlineBeatmapSetID == BeatmapSet?.OnlineBeatmapSetID)
downloadButtonsContainer.FadeOut(transition_duration);
});
private void download(bool noVideo)
{
if (beatmaps.GetExistingDownload(BeatmapSet) != null)
{
downloadButtonsContainer.MoveToX(-5, 50, Easing.OutSine).Then()
.MoveToX(5, 100, Easing.InOutSine).Then()
.MoveToX(-5, 100, Easing.InOutSine).Then()
.MoveToX(0, 50, Easing.InSine).Then();
return;
}
beatmaps.Download(BeatmapSet, noVideo);
}
}
}
+5 -3
View File
@@ -21,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapSet
private const float metadata_width = 225;
private const float spacing = 20;
private readonly MetadataSection source, tags;
private readonly MetadataSection description, source, tags;
private readonly Box successRateBackground;
private readonly SuccessRate successRate;
@@ -83,7 +83,7 @@ namespace osu.Game.Overlays.BeatmapSet
Child = new Container
{
RelativeSizeAxes = Axes.Both,
Child = new MetadataSection("Description"),
Child = description = new MetadataSection("Description"),
},
},
new Container
@@ -135,6 +135,8 @@ namespace osu.Game.Overlays.BeatmapSet
private void load(OsuColour colours)
{
successRateBackground.Colour = colours.GrayE;
source.TextColour = description.TextColour = colours.Gray5;
tags.TextColour = colours.BlueDark;
updateDisplay();
}
@@ -193,7 +195,7 @@ namespace osu.Game.Overlays.BeatmapSet
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
header.Colour = textFlow.Colour = colours.Gray5;
header.Colour = colours.Gray5;
}
}
}
+2 -1
View File
@@ -166,13 +166,14 @@ namespace osu.Game.Overlays.Direct
},
},
},
new DownloadButton(SetInfo)
new DownloadButton
{
Size = new Vector2(30),
Margin = new MarginPadding(horizontal_padding),
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Colour = colours.Gray5,
Action = StartDownload
},
},
},
+34 -65
View File
@@ -12,31 +12,28 @@ using osu.Game.Graphics.Sprites;
using osu.Framework.Allocation;
using osu.Framework.Localisation;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Game.Beatmaps;
namespace osu.Game.Overlays.Direct
{
public class DirectListPanel : DirectPanel
{
private const float transition_duration = 120;
private const float horizontal_padding = 10;
private const float vertical_padding = 5;
private const float height = 70;
private PlayButton playButton;
private Box progressBar;
private Container downloadContainer;
protected override PlayButton PlayButton => playButton;
protected override Box PreviewBar => progressBar;
public DirectListPanel(BeatmapSetInfo beatmap) : base(beatmap)
{
RelativeSizeAxes = Axes.X;
Height = height;
}
private PlayButton playButton;
private Box progressBar;
protected override PlayButton PlayButton => playButton;
protected override Box PreviewBar => progressBar;
[BackgroundDependencyLoader]
private void load(LocalisationEngine localisation, OsuColour colours)
{
@@ -62,7 +59,7 @@ namespace osu.Game.Overlays.Direct
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
LayoutEasing = Easing.OutQuint,
LayoutDuration = transition_duration,
LayoutDuration = 120,
Spacing = new Vector2(10, 0),
Children = new Drawable[]
{
@@ -107,69 +104,53 @@ namespace osu.Game.Overlays.Direct
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
LayoutEasing = Easing.OutQuint,
LayoutDuration = transition_duration,
Direction = FillDirection.Vertical,
Margin = new MarginPadding { Right = height - vertical_padding * 2 + vertical_padding },
Children = new Drawable[]
{
downloadContainer = new Container
new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Alpha = 0,
Child = new DownloadButton(SetInfo)
{
Size = new Vector2(height - vertical_padding * 2),
Margin = new MarginPadding { Left = vertical_padding },
},
Margin = new MarginPadding { Right = 1 },
},
new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0),
new FillFlowContainer
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
Direction = FillDirection.Horizontal,
Children = new[]
{
new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0)
new OsuSpriteText
{
Margin = new MarginPadding { Right = 1 },
},
new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0),
new FillFlowContainer
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Children = new[]
{
new OsuSpriteText
{
Text = "mapped by ",
TextSize = 14,
},
new OsuSpriteText
{
Text = SetInfo.Metadata.Author.Username,
TextSize = 14,
Font = @"Exo2.0-SemiBoldItalic",
},
},
Text = "mapped by ",
TextSize = 14,
},
new OsuSpriteText
{
Text = $"from {SetInfo.Metadata.Source}",
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Text = SetInfo.Metadata.Author.Username,
TextSize = 14,
Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f,
Font = @"Exo2.0-SemiBoldItalic",
},
},
},
new OsuSpriteText
{
Text = $"from {SetInfo.Metadata.Source}",
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
TextSize = 14,
Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f,
},
},
},
new DownloadButton
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Size = new Vector2(height - vertical_padding * 2),
Action = StartDownload
},
},
},
progressBar = new Box
@@ -184,17 +165,5 @@ namespace osu.Game.Overlays.Direct
},
});
}
protected override bool OnHover(InputState state)
{
downloadContainer.FadeIn(transition_duration, Easing.InOutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
downloadContainer.FadeOut(transition_duration, Easing.InOutQuint);
base.OnHoverLost(state);
}
}
}
+16
View File
@@ -147,6 +147,22 @@ namespace osu.Game.Overlays.Direct
protected void ShowInformation() => beatmapSetOverlay?.ShowBeatmapSet(SetInfo);
protected void StartDownload()
{
if (beatmaps.GetExistingDownload(SetInfo) != null)
{
// we already have an active download running.
content.MoveToX(-5, 50, Easing.OutSine).Then()
.MoveToX(5, 100, Easing.InOutSine).Then()
.MoveToX(-5, 100, Easing.InOutSine).Then()
.MoveToX(0, 50, Easing.InSine).Then();
return;
}
beatmaps.Download(SetInfo);
}
private void attachDownload(DownloadBeatmapSetRequest request)
{
if (request.BeatmapSet.OnlineBeatmapSetID != SetInfo.OnlineBeatmapSetID)
+1 -24
View File
@@ -3,8 +3,6 @@
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using OpenTK;
@@ -15,12 +13,10 @@ namespace osu.Game.Overlays.Direct
{
private readonly SpriteIcon icon;
public DownloadButton(BeatmapSetInfo set, bool noVideo = false)
public DownloadButton()
{
BeatmapSetDownloader downloader;
Children = new Drawable[]
{
downloader = new BeatmapSetDownloader(set, noVideo),
icon = new SpriteIcon
{
Anchor = Anchor.Centre,
@@ -29,25 +25,6 @@ namespace osu.Game.Overlays.Direct
Icon = FontAwesome.fa_osu_chevron_down_o,
},
};
Action = () =>
{
if (!downloader.Download())
{
Content.MoveToX(-5, 50, Easing.OutSine).Then()
.MoveToX(5, 100, Easing.InOutSine).Then()
.MoveToX(-5, 100, Easing.InOutSine).Then()
.MoveToX(0, 50, Easing.InSine);
}
};
downloader.Downloaded.ValueChanged += d =>
{
if (d)
this.FadeOut(200);
else
this.FadeIn(200);
};
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
+23 -2
View File
@@ -28,6 +28,7 @@ namespace osu.Game.Overlays
private APIAccess api;
private RulesetStore rulesets;
private BeatmapManager beatmaps;
private readonly FillFlowContainer resultCountsContainer;
private readonly OsuSpriteText resultCountsText;
@@ -176,14 +177,24 @@ namespace osu.Game.Overlays
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, APIAccess api, RulesetStore rulesets)
private void load(OsuColour colours, APIAccess api, RulesetStore rulesets, BeatmapManager beatmaps)
{
this.api = api;
this.rulesets = rulesets;
this.beatmaps = beatmaps;
resultCountsContainer.Colour = colours.Yellow;
beatmaps.ItemAdded += setAdded;
}
private void setAdded(BeatmapSetInfo set) => Schedule(() =>
{
// if a new map was imported, we should remove it from search results (download completed etc.)
panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire();
BeatmapSets = BeatmapSets?.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID);
});
private void updateResultCounts()
{
resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, Easing.OutQuint);
@@ -286,7 +297,9 @@ namespace osu.Game.Overlays
{
Task.Run(() =>
{
var sets = response.Select(r => r.ToBeatmapSet(rulesets)).ToList();
var onlineIds = response.Select(r => r.OnlineBeatmapSetID).ToList();
var presentOnlineIds = beatmaps.QueryBeatmapSets(s => onlineIds.Contains(s.OnlineBeatmapSetID) && !s.DeletePending).Select(r => r.OnlineBeatmapSetID).ToList();
var sets = response.Select(r => r.ToBeatmapSet(rulesets)).Where(b => !presentOnlineIds.Contains(b.OnlineBeatmapSetID)).ToList();
// may not need scheduling; loads async internally.
Schedule(() =>
@@ -310,6 +323,14 @@ namespace osu.Game.Overlays
private int distinctCount(List<string> list) => list.Distinct().ToArray().Length;
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (beatmaps != null)
beatmaps.ItemAdded -= setAdded;
}
public class ResultCounts
{
public readonly int Artists;
+2 -2
View File
@@ -73,13 +73,13 @@ namespace osu.Game.Overlays.Music
}
[BackgroundDependencyLoader]
private void load(BeatmapManager beatmaps, IBindableBeatmap beatmap)
private void load(BeatmapManager beatmaps, OsuGameBase osuGame)
{
beatmaps.GetAllUsableBeatmapSets().ForEach(addBeatmapSet);
beatmaps.ItemAdded += addBeatmapSet;
beatmaps.ItemRemoved += removeBeatmapSet;
beatmapBacking.BindTo(beatmap);
beatmapBacking.BindTo(osuGame.Beatmap);
beatmapBacking.ValueChanged += _ => updateSelectedSet();
}
+13 -16
View File
@@ -21,22 +21,17 @@ namespace osu.Game.Overlays.Music
private const float transition_duration = 600;
private const float playlist_height = 510;
/// <summary>
/// Invoked when the order of an item in the list has changed.
/// The second parameter indicates the new index of the item.
/// </summary>
public Action<BeatmapSetInfo, int> OrderChanged;
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
private BeatmapManager beatmaps;
private FilterControl filter;
private PlaylistList list;
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
[BackgroundDependencyLoader]
private void load(OsuColour colours, BindableBeatmap beatmap, BeatmapManager beatmaps)
private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours)
{
this.beatmap.BindTo(beatmap);
this.beatmaps = beatmaps;
Children = new Drawable[]
@@ -78,13 +73,15 @@ namespace osu.Game.Overlays.Music
},
};
beatmapBacking.BindTo(game.Beatmap);
filter.Search.OnCommit = (sender, newText) =>
{
BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault();
if (toSelect != null)
BeatmapInfo beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault();
if (beatmap != null)
{
beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect);
beatmap.Value.Track.Restart();
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(beatmap);
beatmapBacking.Value.Track.Restart();
}
};
}
@@ -108,14 +105,14 @@ namespace osu.Game.Overlays.Music
private void itemSelected(BeatmapSetInfo set)
{
if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1))
if (set.ID == (beatmapBacking.Value?.BeatmapSetInfo?.ID ?? -1))
{
beatmap.Value?.Track?.Seek(0);
beatmapBacking.Value?.Track?.Seek(0);
return;
}
beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First());
beatmap.Value.Track.Restart();
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First());
beatmapBacking.Value.Track.Restart();
}
}
+18 -13
View File
@@ -30,8 +30,11 @@ namespace osu.Game.Overlays
public class MusicController : OsuFocusedOverlayContainer
{
private const float player_height = 130;
private const float transition_length = 800;
private const float progress_height = 10;
private const float bottom_black_area_height = 55;
private Drawable background;
@@ -46,17 +49,16 @@ namespace osu.Game.Overlays
private PlaylistOverlay playlist;
private BeatmapManager beatmaps;
private LocalisationEngine localisation;
private BeatmapManager beatmaps;
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
private List<BeatmapSetInfo> beatmapSets;
private BeatmapSetInfo currentSet;
private Container dragContainer;
private Container playerContainer;
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
public MusicController()
{
Width = 400;
@@ -95,9 +97,8 @@ namespace osu.Game.Overlays
}
[BackgroundDependencyLoader]
private void load(BindableBeatmap beatmap, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation)
private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation)
{
this.beatmap.BindTo(beatmap);
this.beatmaps = beatmaps;
this.localisation = localisation;
@@ -223,6 +224,8 @@ namespace osu.Game.Overlays
beatmaps.ItemAdded += handleBeatmapAdded;
beatmaps.ItemRemoved += handleBeatmapRemoved;
beatmapBacking.BindTo(game.Beatmap);
playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint);
}
@@ -237,8 +240,10 @@ namespace osu.Game.Overlays
protected override void LoadComplete()
{
beatmap.BindValueChanged(beatmapChanged, true);
beatmap.BindDisabledChanged(beatmapDisabledChanged, true);
beatmapBacking.ValueChanged += beatmapChanged;
beatmapBacking.DisabledChanged += beatmapDisabledChanged;
beatmapBacking.TriggerChange();
base.LoadComplete();
}
@@ -271,7 +276,7 @@ namespace osu.Game.Overlays
playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o;
if (track.HasCompleted && !track.Looping && !beatmap.Disabled && beatmapSets.Any())
if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && beatmapSets.Any())
next();
}
else
@@ -284,7 +289,7 @@ namespace osu.Game.Overlays
if (track == null)
{
if (!beatmap.Disabled)
if (!beatmapBacking.Disabled)
next(true);
return;
}
@@ -302,8 +307,8 @@ namespace osu.Game.Overlays
var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault();
if (playable != null)
{
beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
beatmap.Value.Track.Restart();
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking);
beatmapBacking.Value.Track.Restart();
}
}
@@ -315,8 +320,8 @@ namespace osu.Game.Overlays
var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault();
if (playable != null)
{
beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
beatmap.Value.Track.Restart();
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking);
beatmapBacking.Value.Track.Restart();
}
}
+26 -23
View File
@@ -22,6 +22,11 @@ namespace osu.Game.Overlays
public const float TRANSITION_LENGTH = 600;
/// <summary>
/// Whether posted notifications should be processed.
/// </summary>
public readonly BindableBool Enabled = new BindableBool(true);
private FlowContainer<NotificationSection> sections;
/// <summary>
@@ -29,6 +34,27 @@ namespace osu.Game.Overlays
/// </summary>
public Func<float> GetToolbarHeight;
public NotificationOverlay()
{
ScheduledDelegate notificationsEnabler = null;
Enabled.ValueChanged += v =>
{
if (!IsLoaded)
{
processingPosts = v;
return;
}
notificationsEnabler?.Cancel();
if (v)
// we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed.
notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, 1000);
else
processingPosts = false;
};
}
[BackgroundDependencyLoader]
private void load()
{
@@ -77,29 +103,6 @@ namespace osu.Game.Overlays
};
}
private ScheduledDelegate notificationsEnabler;
private void updateProcessingMode()
{
bool enabled = OverlayActivationMode == OverlayActivation.All || State == Visibility.Visible;
notificationsEnabler?.Cancel();
if (enabled)
// we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed.
notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, State == Visibility.Visible ? 0 : 1000);
else
processingPosts = false;
}
protected override void LoadComplete()
{
base.LoadComplete();
StateChanged += _ => updateProcessingMode();
OverlayActivationMode.ValueChanged += _ => updateProcessingMode();
OverlayActivationMode.TriggerChange();
}
private int totalCount => sections.Select(c => c.DisplayedCount).Sum();
private int unreadCount => sections.Select(c => c.UnreadCount).Sum();
-12
View File
@@ -1,12 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Overlays
{
public enum OverlayActivation
{
Disabled,
UserTriggered,
All
}
}
@@ -107,20 +107,13 @@ namespace osu.Game.Overlays.Profile.Header
visibleBadge = 0;
badgeFlowContainer.Clear();
for (var index = 0; index < badges.Length; index++)
foreach (var badge in badges)
{
int displayIndex = index;
LoadComponentAsync(new DrawableBadge(badges[index])
LoadComponentAsync(new DrawableBadge(badge)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
}, asyncBadge =>
{
badgeFlowContainer.Add(asyncBadge);
// load in stable order regardless of async load order.
badgeFlowContainer.SetLayoutPosition(asyncBadge, displayIndex);
});
}, badgeFlowContainer.Add);
}
}
@@ -1,26 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Game.Configuration;
namespace osu.Game.Overlays.Settings.Sections.Gameplay
{
public class ModsSettings : SettingsSubsection
{
protected override string Header => "Mods";
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
Children = new[]
{
new SettingsCheckbox
{
LabelText = "Increase visibility of first object with \"Hidden\" mod",
Bindable = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility)
},
};
}
}
}
@@ -21,8 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections
{
new GeneralSettings(),
new SongSelectSettings(),
new ScrollingSettings(),
new ModsSettings(),
new ScrollingSettings()
};
}
+1 -1
View File
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Development;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
@@ -11,7 +12,6 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets;
using OpenTK;
using OpenTK.Graphics;
using DebugUtils = osu.Game.Utils.DebugUtils;
namespace osu.Game.Overlays.Settings
{
-17
View File
@@ -10,8 +10,6 @@ using osu.Framework.Input;
using osu.Game.Graphics;
using OpenTK;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
namespace osu.Game.Overlays.Toolbar
{
@@ -31,8 +29,6 @@ namespace osu.Game.Overlays.Toolbar
private const float alpha_hovering = 0.8f;
private const float alpha_normal = 0.6f;
private readonly Bindable<OverlayActivation> overlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
public Toolbar()
{
Children = new Drawable[]
@@ -80,19 +76,6 @@ namespace osu.Game.Overlays.Toolbar
Size = new Vector2(1, HEIGHT);
}
[BackgroundDependencyLoader(true)]
private void load(OsuGame osuGame)
{
if (osuGame != null)
overlayActivationMode.BindTo(osuGame.OverlayActivationMode);
StateChanged += visibility =>
{
if (overlayActivationMode == OverlayActivation.Disabled)
State = Visibility.Hidden;
};
}
public class ToolbarBackground : Container
{
private readonly Box solidBackground;
+2 -18
View File
@@ -167,25 +167,9 @@ namespace osu.Game.Overlays.Volume
private set => Bindable.Value = value;
}
private const float adjust_step = 0.05f;
public void Increase() => Volume += 0.05f;
public void Increase() => adjust(1);
public void Decrease() => adjust(-1);
private void adjust(int direction)
{
float amount = adjust_step * direction;
var mouse = GetContainingInputManager().CurrentState.Mouse;
if (mouse.HasPreciseScroll)
{
float scrollDelta = mouse.ScrollDelta.Y;
if (scrollDelta != 0)
amount *= Math.Abs(scrollDelta / 10);
}
Volume += amount;
}
public void Decrease() => Volume -= 0.05f;
public bool OnPressed(GlobalAction action)
{
+3 -3
View File
@@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Edit
private RulesetContainer rulesetContainer;
private readonly List<Container> layerContainers = new List<Container>();
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
protected HitObjectComposer(Ruleset ruleset)
{
@@ -38,9 +38,9 @@ namespace osu.Game.Rulesets.Edit
}
[BackgroundDependencyLoader]
private void load(IBindableBeatmap beatmap, IFrameBasedClock framedClock)
private void load(OsuGameBase osuGame, IFrameBasedClock framedClock)
{
this.beatmap.BindTo(beatmap);
beatmap.BindTo(osuGame.Beatmap);
try
{
-15
View File
@@ -1,15 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Configuration;
namespace osu.Game.Rulesets.Mods
{
/// <summary>
/// An interface for mods that require reading access to the osu! configuration.
/// </summary>
public interface IReadFromConfig
{
void ReadFromConfig(OsuConfigManager config);
}
}
+1 -22
View File
@@ -1,37 +1,16 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Configuration;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using System.Collections.Generic;
using System.Linq;
namespace osu.Game.Rulesets.Mods
{
public abstract class ModHidden : Mod, IReadFromConfig, IApplicableToDrawableHitObjects
public abstract class ModHidden : Mod
{
public override string Name => "Hidden";
public override string ShortenedName => "HD";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
public override ModType Type => ModType.DifficultyIncrease;
public override bool Ranked => true;
protected Bindable<bool> IncreaseFirstObjectVisibility = new Bindable<bool>();
public void ReadFromConfig(OsuConfigManager config)
{
IncreaseFirstObjectVisibility = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility);
}
public virtual void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
{
// todo: fix ordering of objects so we don't have to do this (#2740).
foreach (var d in drawables.Reverse().Skip(IncreaseFirstObjectVisibility ? 1 : 0))
d.ApplyCustomUpdateState += ApplyHiddenState;
}
protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state) { }
}
}
+6 -10
View File
@@ -57,7 +57,6 @@ namespace osu.Game.Rulesets.UI
public abstract IEnumerable<HitObject> Objects { get; }
private readonly Lazy<Playfield> playfield;
/// <summary>
/// The playfield.
/// </summary>
@@ -131,6 +130,7 @@ namespace osu.Game.Rulesets.UI
HasReplayLoaded.Value = ReplayInputManager.ReplayInputHandler != null;
}
/// <summary>
/// Creates the cursor. May be null if the <see cref="RulesetContainer"/> doesn't provide a custom cursor.
/// </summary>
@@ -194,7 +194,6 @@ namespace osu.Game.Rulesets.UI
protected override Container<Drawable> Content => content;
private Container content;
private IEnumerable<Mod> mods;
/// <summary>
/// Whether to assume the beatmap passed into this <see cref="RulesetContainer{TObject}"/> is for the current ruleset.
@@ -217,10 +216,13 @@ namespace osu.Game.Rulesets.UI
KeyBindingInputManager = CreateInputManager();
KeyBindingInputManager.RelativeSizeAxes = Axes.Both;
// Add mods, should always be the last thing applied to give full control to mods
applyMods(Mods);
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
private void load()
{
KeyBindingInputManager.Add(content = new Container
{
@@ -233,9 +235,6 @@ namespace osu.Game.Rulesets.UI
if (Cursor != null)
KeyBindingInputManager.Add(Cursor);
// Apply mods
applyMods(Mods, config);
loadObjects();
}
@@ -243,16 +242,13 @@ namespace osu.Game.Rulesets.UI
/// Applies the active mods to this RulesetContainer.
/// </summary>
/// <param name="mods"></param>
private void applyMods(IEnumerable<Mod> mods, OsuConfigManager config)
private void applyMods(IEnumerable<Mod> mods)
{
if (mods == null)
return;
foreach (var mod in mods.OfType<IApplicableToRulesetContainer<TObject>>())
mod.ApplyToRulesetContainer(this);
foreach (var mod in mods.OfType<IReadFromConfig>())
mod.ReadFromConfig(config);
}
public override void SetReplay(Replay replay)
@@ -17,7 +17,7 @@ namespace osu.Game.Screens.Edit.Components
private const float corner_radius = 5;
private const float contents_padding = 15;
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
protected Track Track => Beatmap.Value.Track;
private readonly Drawable background;
@@ -42,9 +42,8 @@ namespace osu.Game.Screens.Edit.Components
}
[BackgroundDependencyLoader]
private void load(IBindableBeatmap beatmap, OsuColour colours)
private void load(OsuColour colours)
{
Beatmap.BindTo(beatmap);
background.Colour = colours.Gray1;
}
}
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using OpenTK;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
@@ -16,7 +15,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
/// </summary>
public abstract class TimelinePart : CompositeDrawable
{
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
public Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
private readonly Container timeline;
@@ -31,12 +30,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
};
}
[BackgroundDependencyLoader]
private void load(IBindableBeatmap beatmap)
{
Beatmap.BindTo(beatmap);
}
private void updateRelativeChildSize()
{
// the track may not be loaded completely (only has a length once it is).
@@ -20,17 +20,19 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary
[BackgroundDependencyLoader]
private void load(OsuColour colours, IAdjustableClock adjustableClock)
{
TimelinePart markerPart, controlPointPart, bookmarkPart, breakPart;
Children = new Drawable[]
{
new MarkerPart(adjustableClock) { RelativeSizeAxes = Axes.Both },
new ControlPointPart
markerPart = new MarkerPart(adjustableClock) { RelativeSizeAxes = Axes.Both },
controlPointPart = new ControlPointPart
{
Anchor = Anchor.Centre,
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.Both,
Height = 0.35f
},
new BookmarkPart
bookmarkPart = new BookmarkPart
{
Anchor = Anchor.Centre,
Origin = Anchor.TopCentre,
@@ -65,7 +67,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary
},
}
},
new BreakPart
breakPart = new BreakPart
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -73,6 +75,11 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary
Height = 0.25f
}
};
markerPart.Beatmap.BindTo(Beatmap);
controlPointPart.Beatmap.BindTo(Beatmap);
bookmarkPart.Beatmap.BindTo(Beatmap);
breakPart.Beatmap.BindTo(Beatmap);
}
}
}
+9 -5
View File
@@ -41,14 +41,14 @@ namespace osu.Game.Screens.Edit
private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
=> dependencies = new DependencyContainer(parent);
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
// TODO: should probably be done at a RulesetContainer level to share logic with Player.
var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock();
clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false };
clock = new EditorClock(Beatmap, beatDivisor) { IsCoupled = false };
clock.ChangeSource(sourceClock);
dependencies.CacheAs<IFrameBasedClock>(clock);
@@ -128,9 +128,9 @@ namespace osu.Game.Screens.Edit
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Right = 10 },
Child = new TimeInfoContainer { RelativeSizeAxes = Axes.Both },
Child = timeInfo = new TimeInfoContainer { RelativeSizeAxes = Axes.Both },
},
new SummaryTimeline
timeline = new SummaryTimeline
{
RelativeSizeAxes = Axes.Both,
},
@@ -138,7 +138,7 @@ namespace osu.Game.Screens.Edit
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = 10 },
Child = new PlaybackControl { RelativeSizeAxes = Axes.Both },
Child = playback = new PlaybackControl { RelativeSizeAxes = Axes.Both },
}
},
}
@@ -148,6 +148,9 @@ namespace osu.Game.Screens.Edit
},
};
timeInfo.Beatmap.BindTo(Beatmap);
timeline.Beatmap.BindTo(Beatmap);
playback.Beatmap.BindTo(Beatmap);
menuBar.Mode.ValueChanged += onModeChanged;
bottomBackground.Colour = colours.Gray2;
@@ -175,6 +178,7 @@ namespace osu.Game.Screens.Edit
break;
}
currentScreen.Beatmap.BindTo(Beatmap);
LoadComponentAsync(currentScreen, screenContainer.Add);
}
+4 -3
View File
@@ -3,6 +3,7 @@
using System;
using System.Linq;
using osu.Framework.Configuration;
using osu.Framework.MathUtils;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
@@ -23,12 +24,12 @@ namespace osu.Game.Screens.Edit
private readonly BindableBeatDivisor beatDivisor;
public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor)
public EditorClock(Bindable<WorkingBeatmap> beatmap, BindableBeatDivisor beatDivisor)
{
this.beatDivisor = beatDivisor;
ControlPointInfo = beatmap.Beatmap.ControlPointInfo;
TrackLength = beatmap.Track.Length;
ControlPointInfo = beatmap.Value.Beatmap.ControlPointInfo;
TrackLength = beatmap.Value.Track.Length;
}
public EditorClock(ControlPointInfo controlPointInfo, double trackLength, BindableBeatDivisor beatDivisor)
@@ -28,6 +28,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose
if (beatDivisor != null)
this.beatDivisor.BindTo(beatDivisor);
ScrollableTimeline timeline;
Children = new Drawable[]
{
new GridContainer
@@ -64,7 +65,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Right = 5 },
Child = new ScrollableTimeline { RelativeSizeAxes = Axes.Both }
Child = timeline = new ScrollableTimeline { RelativeSizeAxes = Axes.Both }
},
new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both }
},
@@ -93,6 +94,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose
},
};
timeline.Beatmap.BindTo(Beatmap);
var ruleset = Beatmap.Value.BeatmapInfo.Ruleset?.CreateInstance();
if (ruleset == null)
{
@@ -1,6 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Audio;
using osu.Framework.Graphics.Containers;
@@ -10,13 +11,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
{
public class BeatmapWaveformGraph : CompositeDrawable
{
public WorkingBeatmap Beatmap { set => graph.Waveform = value.Waveform; }
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
private readonly WaveformGraph graph;
public BeatmapWaveformGraph()
{
InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both };
Beatmap.ValueChanged += b => graph.Waveform = b.Waveform;
}
/// <summary>
@@ -2,9 +2,11 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
@@ -12,6 +14,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
{
public class ScrollableTimeline : CompositeDrawable
{
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
private readonly ScrollingTimelineContainer timelineContainer;
public ScrollableTimeline()
@@ -113,6 +117,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
hitSoundsCheckbox.Current.Value = true;
waveformCheckbox.Current.Value = true;
timelineContainer.Beatmap.BindTo(Beatmap);
timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current);
}
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using OpenTK;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
@@ -18,8 +17,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
public readonly Bindable<bool> HitObjectsVisible = new Bindable<bool>();
public readonly Bindable<bool> HitSoundsVisible = new Bindable<bool>();
public readonly Bindable<bool> WaveformVisible = new Bindable<bool>();
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
private readonly BeatmapWaveformGraph waveform;
@@ -38,20 +36,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
Content.AutoSizeAxes = Axes.None;
Content.RelativeSizeAxes = Axes.Both;
waveform.Beatmap.BindTo(Beatmap);
WaveformVisible.ValueChanged += waveformVisibilityChanged;
Zoom = 10;
}
[BackgroundDependencyLoader]
private void load(IBindableBeatmap beatmap)
{
this.beatmap.BindTo(beatmap);
this.beatmap.BindValueChanged(beatmapChanged, true);
}
private void beatmapChanged(WorkingBeatmap beatmap) => waveform.Beatmap = beatmap;
private float minZoom = 1;
/// <summary>
/// The minimum zoom level allowed.
@@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -14,7 +13,7 @@ namespace osu.Game.Screens.Edit.Screens
/// </summary>
public class EditorScreen : Container
{
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
protected override Container<Drawable> Content => content;
private readonly Container content;
@@ -28,12 +27,6 @@ namespace osu.Game.Screens.Edit.Screens
InternalChild = content = new Container { RelativeSizeAxes = Axes.Both };
}
[BackgroundDependencyLoader]
private void load(IBindableBeatmap beatmap)
{
Beatmap.BindTo(beatmap);
}
protected override void LoadComplete()
{
base.LoadComplete();
+21 -21
View File
@@ -8,6 +8,7 @@ using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@@ -16,7 +17,6 @@ using osu.Framework.Input.Bindings;
using osu.Framework.Threading;
using osu.Game.Graphics;
using osu.Game.Input.Bindings;
using osu.Game.Overlays;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
@@ -27,6 +27,9 @@ namespace osu.Game.Screens.Menu
{
public event Action<MenuState> StateChanged;
private readonly BindableBool hideOverlaysOnEnter = new BindableBool();
private readonly BindableBool allowOpeningOverlays = new BindableBool();
public Action OnEdit;
public Action OnExit;
public Action OnDirect;
@@ -130,12 +133,15 @@ namespace osu.Game.Screens.Menu
buttonFlow.AddRange(buttonsTopLevel);
}
private OsuGame game;
[BackgroundDependencyLoader(true)]
private void load(AudioManager audio, OsuGame game)
{
this.game = game;
if (game != null)
{
hideOverlaysOnEnter.BindTo(game.HideOverlaysOnEnter);
allowOpeningOverlays.BindTo(game.AllowOpeningOverlays);
}
sampleBack = audio.Sample.Get(@"Menu/button-back-select");
}
@@ -322,21 +328,18 @@ namespace osu.Game.Screens.Menu
case MenuState.Initial:
logoDelayedAction?.Cancel();
logoDelayedAction = Scheduler.AddDelayed(() =>
{
logoTracking = false;
{
logoTracking = false;
if (game != null)
{
game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.All;
game.Toolbar.Hide();
}
hideOverlaysOnEnter.Value = true;
allowOpeningOverlays.Value = false;
logo.ClearTransforms(targetMember: nameof(Position));
logo.RelativePositionAxes = Axes.Both;
logo.ClearTransforms(targetMember: nameof(Position));
logo.RelativePositionAxes = Axes.Both;
logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo);
logo.ScaleTo(1, 800, Easing.OutExpo);
}, buttonArea.Alpha * 150);
logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo);
logo.ScaleTo(1, 800, Easing.OutExpo);
}, buttonArea.Alpha * 150);
break;
case MenuState.TopLevel:
case MenuState.Play:
@@ -363,11 +366,8 @@ namespace osu.Game.Screens.Menu
if (impact)
logo.Impact();
if (game != null)
{
game.OverlayActivationMode.Value = OverlayActivation.All;
game.Toolbar.State = Visibility.Visible;
}
hideOverlaysOnEnter.Value = false;
allowOpeningOverlays.Value = true;
}, 200);
break;
default:
+1 -2
View File
@@ -9,7 +9,6 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
using osu.Game.Overlays;
namespace osu.Game.Screens.Menu
{
@@ -20,7 +19,7 @@ namespace osu.Game.Screens.Menu
private Color4 iconColour;
protected override bool HideOverlaysOnEnter => true;
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
protected override bool AllowOpeningOverlays => false;
public override bool CursorVisible => false;
+6 -11
View File
@@ -15,7 +15,6 @@ using osu.Game.IO.Archives;
using osu.Game.Screens.Backgrounds;
using OpenTK;
using OpenTK.Graphics;
using osu.Game.Overlays;
namespace osu.Game.Screens.Menu
{
@@ -28,14 +27,12 @@ namespace osu.Game.Screens.Menu
/// </summary>
public bool DidLoadMenu;
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
private MainMenu mainMenu;
private SampleChannel welcome;
private SampleChannel seeya;
protected override bool HideOverlaysOnEnter => true;
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
protected override bool AllowOpeningOverlays => false;
public override bool CursorVisible => false;
@@ -44,13 +41,11 @@ namespace osu.Game.Screens.Menu
private Bindable<bool> menuVoice;
private Bindable<bool> menuMusic;
private Track track;
private WorkingBeatmap introBeatmap;
private WorkingBeatmap beatmap;
[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, BindableBeatmap beatmap)
private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game)
{
this.beatmap.BindTo(beatmap);
menuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice);
menuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic);
@@ -77,8 +72,8 @@ namespace osu.Game.Screens.Menu
}
}
introBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
track = introBeatmap.Track;
beatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
track = beatmap.Track;
welcome = audio.Sample.Get(@"welcome");
seeya = audio.Sample.Get(@"seeya");
@@ -95,7 +90,7 @@ namespace osu.Game.Screens.Menu
if (!resuming)
{
beatmap.Value = introBeatmap;
Game.Beatmap.Value = beatmap;
if (menuVoice)
welcome.Play();
+3 -3
View File
@@ -21,7 +21,7 @@ namespace osu.Game.Screens.Menu
{
public class LogoVisualisation : Drawable, IHasAccentColour
{
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
/// <summary>
/// The number of bars to jump each update iteration.
@@ -78,9 +78,9 @@ namespace osu.Game.Screens.Menu
}
[BackgroundDependencyLoader]
private void load(ShaderManager shaders, IBindableBeatmap beatmap)
private void load(ShaderManager shaders, OsuGameBase game)
{
this.beatmap.BindTo(beatmap);
beatmap.BindTo(game.Beatmap);
shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED);
}
+1
View File
@@ -25,6 +25,7 @@ namespace osu.Game.Screens.Menu
private readonly ButtonSystem buttons;
protected override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial;
protected override bool AllowOpeningOverlays => buttons.State != MenuState.Initial;
protected override bool AllowBackButton => buttons.State != MenuState.Initial;
+3 -3
View File
@@ -22,7 +22,7 @@ namespace osu.Game.Screens.Menu
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
private Box leftBox;
private Box rightBox;
@@ -45,9 +45,9 @@ namespace osu.Game.Screens.Menu
}
[BackgroundDependencyLoader]
private void load(IBindableBeatmap beatmap, OsuColour colours)
private void load(OsuGameBase game, OsuColour colours)
{
this.beatmap.BindTo(beatmap);
beatmap.BindTo(game.Beatmap);
// linear colour looks better in this case, so let's use it for now.
Color4 gradientDark = colours.Blue.Opacity(0).ToLinear();

Some files were not shown because too many files have changed in this diff Show More