diff --git a/osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs b/osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs
index 394fd75488..1d207d04c7 100644
--- a/osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs
+++ b/osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs
@@ -8,7 +8,7 @@ using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.IO;
using osu.Game.IO.Archives;
-using osu.Game.Resources;
+using osu.Game.Tests.Resources;
namespace osu.Game.Benchmarks
{
@@ -18,8 +18,8 @@ namespace osu.Game.Benchmarks
public override void SetUp()
{
- using (var resources = new DllResourceStore(OsuResources.ResourceAssembly))
- using (var archive = resources.GetStream("Beatmaps/241526 Soleily - Renatus.osz"))
+ using (var resources = new DllResourceStore(typeof(TestResources).Assembly))
+ using (var archive = resources.GetStream("Resources/Archives/241526 Soleily - Renatus.osz"))
using (var reader = new ZipArchiveReader(archive))
reader.GetStream("Soleily - Renatus (Gamu) [Insane].osu").CopyTo(beatmapStream);
}
diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
index 88fe8f1150..41e726e05c 100644
--- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
+++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
@@ -13,6 +13,7 @@
+
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
index cdf78a5902..75dfbf45f2 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
@@ -4,6 +4,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using osu.Framework.Allocation;
+using osu.Framework.Caching;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
@@ -12,6 +16,7 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Edit.Compose.Components;
+using osuTK;
namespace osu.Game.Rulesets.Osu.Edit
{
@@ -32,9 +37,80 @@ namespace osu.Game.Rulesets.Osu.Edit
new SpinnerCompositionTool()
};
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ LayerBelowRuleset.Add(distanceSnapGridContainer = new Container { RelativeSizeAxes = Axes.Both });
+
+ EditorBeatmap.SelectedHitObjects.CollectionChanged += (_, __) => updateDistanceSnapGrid();
+ EditorBeatmap.PlacementObject.ValueChanged += _ => updateDistanceSnapGrid();
+ }
+
protected override ComposeBlueprintContainer CreateBlueprintContainer() => new OsuBlueprintContainer(HitObjects);
- protected override DistanceSnapGrid CreateDistanceSnapGrid(IEnumerable selectedHitObjects)
+ private DistanceSnapGrid distanceSnapGrid;
+ private Container distanceSnapGridContainer;
+
+ private readonly Cached distanceSnapGridCache = new Cached();
+ private double? lastDistanceSnapGridTime;
+
+ protected override void Update()
+ {
+ base.Update();
+
+ if (!(BlueprintContainer.CurrentTool is SelectTool))
+ {
+ if (EditorClock.CurrentTime != lastDistanceSnapGridTime)
+ {
+ distanceSnapGridCache.Invalidate();
+ lastDistanceSnapGridTime = EditorClock.CurrentTime;
+ }
+
+ if (!distanceSnapGridCache.IsValid)
+ updateDistanceSnapGrid();
+ }
+ }
+
+ public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition)
+ {
+ if (distanceSnapGrid == null)
+ return base.SnapScreenSpacePositionToValidTime(screenSpacePosition);
+
+ (Vector2 pos, double time) = distanceSnapGrid.GetSnappedPosition(distanceSnapGrid.ToLocalSpace(screenSpacePosition));
+
+ return new SnapResult(distanceSnapGrid.ToScreenSpace(pos), time);
+ }
+
+ private void updateDistanceSnapGrid()
+ {
+ distanceSnapGridContainer.Clear();
+ distanceSnapGridCache.Invalidate();
+
+ switch (BlueprintContainer.CurrentTool)
+ {
+ case SelectTool _:
+ if (!EditorBeatmap.SelectedHitObjects.Any())
+ return;
+
+ distanceSnapGrid = createDistanceSnapGrid(EditorBeatmap.SelectedHitObjects);
+ break;
+
+ default:
+ if (!CursorInPlacementArea)
+ return;
+
+ distanceSnapGrid = createDistanceSnapGrid(Enumerable.Empty());
+ break;
+ }
+
+ if (distanceSnapGrid != null)
+ {
+ distanceSnapGridContainer.Add(distanceSnapGrid);
+ distanceSnapGridCache.Validate();
+ }
+ }
+
+ private DistanceSnapGrid createDistanceSnapGrid(IEnumerable selectedHitObjects)
{
if (BlueprintContainer.CurrentTool is SpinnerCompositionTool)
return null;
@@ -42,7 +118,8 @@ namespace osu.Game.Rulesets.Osu.Edit
var objects = selectedHitObjects.ToList();
if (objects.Count == 0)
- return createGrid(h => h.StartTime <= EditorClock.CurrentTime);
+ // use accurate time value to give more instantaneous feedback to the user.
+ return createGrid(h => h.StartTime <= EditorClock.CurrentTimeAccurate);
double minTime = objects.Min(h => h.StartTime);
return createGrid(h => h.StartTime < minTime, objects.Count + 1);
diff --git a/osu.Game.Tests/Visual/Editing/TestScenePlaybackControl.cs b/osu.Game.Tests/Visual/Editing/TestScenePlaybackControl.cs
index 3af976cae0..6aa884a197 100644
--- a/osu.Game.Tests/Visual/Editing/TestScenePlaybackControl.cs
+++ b/osu.Game.Tests/Visual/Editing/TestScenePlaybackControl.cs
@@ -4,8 +4,8 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
-using osu.Framework.Timing;
using osu.Game.Beatmaps;
+using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Components;
using osuTK;
@@ -17,9 +17,8 @@ namespace osu.Game.Tests.Visual.Editing
[BackgroundDependencyLoader]
private void load()
{
- var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
- Dependencies.CacheAs(clock);
- Dependencies.CacheAs(clock);
+ var clock = new EditorClock { IsCoupled = false };
+ Dependencies.CacheAs(clock);
var playback = new PlaybackControl
{
diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs
index 01ef7e6170..fdb8781563 100644
--- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs
+++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs
@@ -7,7 +7,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Edit;
@@ -69,7 +68,7 @@ namespace osu.Game.Tests.Visual.Editing
private IBindable beatmap { get; set; }
[Resolved]
- private IAdjustableClock adjustableClock { get; set; }
+ private EditorClock editorClock { get; set; }
public AudioVisualiser()
{
@@ -96,13 +95,15 @@ namespace osu.Game.Tests.Visual.Editing
base.Update();
if (beatmap.Value.Track.IsLoaded)
- marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length);
+ marker.X = (float)(editorClock.CurrentTime / beatmap.Value.Track.Length);
}
}
private class StartStopButton : OsuButton
{
- private IAdjustableClock adjustableClock;
+ [Resolved]
+ private EditorClock editorClock { get; set; }
+
private bool started;
public StartStopButton()
@@ -114,22 +115,16 @@ namespace osu.Game.Tests.Visual.Editing
Action = onClick;
}
- [BackgroundDependencyLoader]
- private void load(IAdjustableClock adjustableClock)
- {
- this.adjustableClock = adjustableClock;
- }
-
private void onClick()
{
if (started)
{
- adjustableClock.Stop();
+ editorClock.Stop();
Text = "Start";
}
else
{
- adjustableClock.Start();
+ editorClock.Start();
Text = "Stop";
}
diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs
index b286c054e9..f626b45e42 100644
--- a/osu.Game/Beatmaps/BeatmapManager.cs
+++ b/osu.Game/Beatmaps/BeatmapManager.cs
@@ -27,7 +27,6 @@ using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
using Decoder = osu.Game.Beatmaps.Formats.Decoder;
-using ZipArchive = SharpCompress.Archives.Zip.ZipArchive;
namespace osu.Game.Beatmaps
{
@@ -66,7 +65,6 @@ namespace osu.Game.Beatmaps
private readonly AudioManager audioManager;
private readonly GameHost host;
private readonly BeatmapOnlineLookupQueue onlineLookupQueue;
- private readonly Storage exportStorage;
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null,
WorkingBeatmap defaultBeatmap = null)
@@ -83,7 +81,6 @@ namespace osu.Game.Beatmaps
beatmaps.BeatmapRestored += b => beatmapRestored.Value = new WeakReference(b);
onlineLookupQueue = new BeatmapOnlineLookupQueue(api, storage);
- exportStorage = storage.GetStorageForDirectory("exports");
}
protected override ArchiveDownloadRequest CreateDownloadRequest(BeatmapSetInfo set, bool minimiseDownloadSize) =>
@@ -214,26 +211,6 @@ namespace osu.Game.Beatmaps
workingCache.Remove(working);
}
- ///
- /// Exports a to an .osz package.
- ///
- /// The to export.
- public void Export(BeatmapSetInfo set)
- {
- var localSet = QueryBeatmapSet(s => s.ID == set.ID);
-
- using (var archive = ZipArchive.Create())
- {
- foreach (var file in localSet.Files)
- archive.AddEntry(file.Filename, Files.Storage.GetStream(file.FileInfo.StoragePath));
-
- using (var outputStream = exportStorage.GetStream($"{set}.osz", FileAccess.Write, FileMode.Create))
- archive.SaveTo(outputStream);
-
- exportStorage.OpenInNativeExplorer();
- }
- }
-
private readonly WeakList workingCache = new WeakList();
///
diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs
index 33b16cbaaf..f21f708f95 100644
--- a/osu.Game/Database/ArchiveModelManager.cs
+++ b/osu.Game/Database/ArchiveModelManager.cs
@@ -22,6 +22,7 @@ using osu.Game.IO.Archives;
using osu.Game.IPC;
using osu.Game.Overlays.Notifications;
using osu.Game.Utils;
+using SharpCompress.Archives.Zip;
using SharpCompress.Common;
using FileInfo = osu.Game.IO.FileInfo;
@@ -82,6 +83,8 @@ namespace osu.Game.Database
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
private ArchiveImportIPCChannel ipc;
+ private readonly Storage exportStorage;
+
protected ArchiveModelManager(Storage storage, IDatabaseContextFactory contextFactory, MutableDatabaseBackedStoreWithFileIncludes modelStore, IIpcHost importHost = null)
{
ContextFactory = contextFactory;
@@ -90,6 +93,8 @@ namespace osu.Game.Database
ModelStore.ItemAdded += item => handleEvent(() => itemAdded.Value = new WeakReference(item));
ModelStore.ItemRemoved += item => handleEvent(() => itemRemoved.Value = new WeakReference(item));
+ exportStorage = storage.GetStorageForDirectory("exports");
+
Files = new FileStore(contextFactory, storage);
if (importHost != null)
@@ -369,6 +374,29 @@ namespace osu.Game.Database
return item;
}, cancellationToken, TaskCreationOptions.HideScheduler, import_scheduler).Unwrap();
+ ///
+ /// Exports an item to a legacy (.zip based) package.
+ ///
+ /// The item to export.
+ public void Export(TModel item)
+ {
+ var retrievedItem = ModelStore.ConsumableItems.FirstOrDefault(s => s.ID == item.ID);
+
+ if (retrievedItem == null)
+ throw new ArgumentException("Specified model could not be found", nameof(item));
+
+ using (var archive = ZipArchive.Create())
+ {
+ foreach (var file in retrievedItem.Files)
+ archive.AddEntry(file.Filename, Files.Storage.GetStream(file.FileInfo.StoragePath));
+
+ using (var outputStream = exportStorage.GetStream($"{getValidFilename(item.ToString())}{HandledExtensions.First()}", FileAccess.Write, FileMode.Create))
+ archive.SaveTo(outputStream);
+
+ exportStorage.OpenInNativeExplorer();
+ }
+ }
+
public void UpdateFile(TModel model, TFileModel file, Stream contents)
{
using (var usage = ContextFactory.GetForWrite())
@@ -710,5 +738,12 @@ namespace osu.Game.Database
}
#endregion
+
+ private string getValidFilename(string filename)
+ {
+ foreach (char c in Path.GetInvalidFileNameChars())
+ filename = filename.Replace(c, '_');
+ return filename;
+ }
}
}
diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs
index 94080f5592..b84b9fec37 100644
--- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs
+++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs
@@ -7,6 +7,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
+using osu.Framework.Logging;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Skinning;
@@ -38,9 +39,11 @@ namespace osu.Game.Overlays.Settings.Sections
private void load(OsuConfigManager config)
{
FlowContent.Spacing = new Vector2(0, 5);
+
Children = new Drawable[]
{
skinDropdown = new SkinSettingsDropdown(),
+ new ExportSkinButton(),
new SettingsSlider
{
LabelText = "Menu cursor size",
@@ -117,5 +120,35 @@ namespace osu.Game.Overlays.Settings.Sections
protected override DropdownMenu CreateMenu() => base.CreateMenu().With(m => m.MaxHeight = 200);
}
}
+
+ private class ExportSkinButton : SettingsButton
+ {
+ [Resolved]
+ private SkinManager skins { get; set; }
+
+ private Bindable currentSkin;
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ Text = "Export selected skin";
+ Action = export;
+
+ currentSkin = skins.CurrentSkin.GetBoundCopy();
+ currentSkin.BindValueChanged(skin => Enabled.Value = skin.NewValue.SkinInfo.ID > 0, true);
+ }
+
+ private void export()
+ {
+ try
+ {
+ skins.Export(currentSkin.Value.SkinInfo);
+ }
+ catch (Exception e)
+ {
+ Logger.Log($"Could not export current skin: {e.Message}", level: LogLevel.Error);
+ }
+ }
+ }
}
}
diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
index b437d81054..edbdd41d81 100644
--- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs
+++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
@@ -3,15 +3,14 @@
using System;
using System.Collections.Generic;
+using System.Collections.Specialized;
using System.Linq;
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Framework.Logging;
-using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Configuration;
@@ -38,22 +37,20 @@ namespace osu.Game.Rulesets.Edit
protected readonly Ruleset Ruleset;
[Resolved]
- protected IFrameBasedClock EditorClock { get; private set; }
+ protected EditorClock EditorClock { get; private set; }
[Resolved]
protected EditorBeatmap EditorBeatmap { get; private set; }
- [Resolved]
- private IAdjustableClock adjustableClock { get; set; }
-
[Resolved]
protected IBeatSnapProvider BeatSnapProvider { get; private set; }
protected ComposeBlueprintContainer BlueprintContainer { get; private set; }
private DrawableEditRulesetWrapper drawableRulesetWrapper;
- private Container distanceSnapGridContainer;
- private DistanceSnapGrid distanceSnapGrid;
+
+ protected readonly Container LayerBelowRuleset = new Container { RelativeSizeAxes = Axes.Both };
+
private readonly List layerContainers = new List();
private InputManager inputManager;
@@ -67,7 +64,7 @@ namespace osu.Game.Rulesets.Edit
}
[BackgroundDependencyLoader]
- private void load(IFrameBasedClock framedClock)
+ private void load()
{
Config = Dependencies.Get().GetConfigFor(Ruleset);
@@ -75,7 +72,7 @@ namespace osu.Game.Rulesets.Edit
{
drawableRulesetWrapper = new DrawableEditRulesetWrapper(CreateDrawableRuleset(Ruleset, EditorBeatmap.PlayableBeatmap))
{
- Clock = framedClock,
+ Clock = EditorClock,
ProcessCustomClock = false
};
}
@@ -87,7 +84,7 @@ namespace osu.Game.Rulesets.Edit
var layerBelowRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChildren(new Drawable[]
{
- distanceSnapGridContainer = new Container { RelativeSizeAxes = Axes.Both },
+ LayerBelowRuleset,
new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }
});
@@ -139,7 +136,7 @@ namespace osu.Game.Rulesets.Edit
setSelectTool();
- BlueprintContainer.SelectionChanged += selectionChanged;
+ EditorBeatmap.SelectedHitObjects.CollectionChanged += selectionChanged;
}
protected override bool OnKeyDown(KeyDownEvent e)
@@ -165,16 +162,6 @@ namespace osu.Game.Rulesets.Edit
inputManager = GetContainingInputManager();
}
- private double lastGridUpdateTime;
-
- protected override void Update()
- {
- base.Update();
-
- if (EditorClock.CurrentTime != lastGridUpdateTime && !(BlueprintContainer.CurrentTool is SelectTool))
- showGridFor(Enumerable.Empty());
- }
-
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
@@ -188,19 +175,13 @@ namespace osu.Game.Rulesets.Edit
});
}
- private void selectionChanged(IEnumerable selectedHitObjects)
+ private void selectionChanged(object sender, NotifyCollectionChangedEventArgs changedArgs)
{
- var hitObjects = selectedHitObjects.ToArray();
-
- if (hitObjects.Any())
+ if (EditorBeatmap.SelectedHitObjects.Any())
{
// ensure in selection mode if a selection is made.
setSelectTool();
-
- showGridFor(hitObjects);
}
- else
- distanceSnapGridContainer.Hide();
}
private void setSelectTool() => toolboxCollection.Items.First().Select();
@@ -209,30 +190,12 @@ namespace osu.Game.Rulesets.Edit
{
BlueprintContainer.CurrentTool = tool;
- if (tool is SelectTool)
- distanceSnapGridContainer.Hide();
- else
- {
+ if (!(tool is SelectTool))
EditorBeatmap.SelectedHitObjects.Clear();
- showGridFor(Enumerable.Empty());
- }
- }
-
- private void showGridFor(IEnumerable selectedHitObjects)
- {
- distanceSnapGridContainer.Clear();
- distanceSnapGrid = CreateDistanceSnapGrid(selectedHitObjects);
-
- if (distanceSnapGrid != null)
- {
- distanceSnapGridContainer.Child = distanceSnapGrid;
- distanceSnapGridContainer.Show();
- }
-
- lastGridUpdateTime = EditorClock.CurrentTime;
}
public override IEnumerable HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects;
+
public override bool CursorInPlacementArea => drawableRulesetWrapper.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
protected abstract IReadOnlyList CompositionTools { get; }
@@ -254,24 +217,14 @@ namespace osu.Game.Rulesets.Edit
{
EditorBeatmap.Add(hitObject);
- if (adjustableClock.CurrentTime < hitObject.StartTime)
- adjustableClock.Seek(hitObject.StartTime);
+ if (EditorClock.CurrentTime < hitObject.StartTime)
+ EditorClock.SeekTo(hitObject.StartTime);
}
-
- showGridFor(Enumerable.Empty());
}
public void Delete(HitObject hitObject) => EditorBeatmap.Remove(hitObject);
- public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition)
- {
- if (distanceSnapGrid == null) return new SnapResult(screenSpacePosition, null);
-
- // TODO: move distance snap grid to OsuHitObjectComposer.
- (Vector2 pos, double time) = distanceSnapGrid.GetSnappedPosition(distanceSnapGrid.ToLocalSpace(screenSpacePosition));
-
- return new SnapResult(distanceSnapGrid.ToScreenSpace(pos), time);
- }
+ public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, null);
public override float GetBeatSnapDistanceAt(double referenceTime)
{
@@ -321,14 +274,6 @@ namespace osu.Game.Rulesets.Edit
///
public abstract bool CursorInPlacementArea { get; }
- ///
- /// Creates the applicable for a selection.
- ///
- /// The selection.
- /// The for . If empty, a grid is returned for the current point in time.
- [CanBeNull]
- protected virtual DistanceSnapGrid CreateDistanceSnapGrid([NotNull] IEnumerable selectedHitObjects) => null;
-
public abstract SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition);
public abstract float GetBeatSnapDistanceAt(double referenceTime);
diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs
index e71ccc33a4..3541a78faa 100644
--- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs
+++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs
@@ -6,10 +6,10 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
-using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Objects;
+using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose;
using osuTK;
@@ -30,10 +30,13 @@ namespace osu.Game.Rulesets.Edit
///
protected readonly HitObject HitObject;
- protected IClock EditorClock { get; private set; }
+ [Resolved(canBeNull: true)]
+ protected EditorClock EditorClock { get; private set; }
private readonly IBindable beatmap = new Bindable();
+ private Bindable startTimeBindable;
+
[Resolved]
private IPlacementHandler placementHandler { get; set; }
@@ -49,13 +52,12 @@ namespace osu.Game.Rulesets.Edit
}
[BackgroundDependencyLoader]
- private void load(IBindable beatmap, IAdjustableClock clock)
+ private void load(IBindable beatmap)
{
this.beatmap.BindTo(beatmap);
- EditorClock = clock;
-
- ApplyDefaultsToHitObject();
+ startTimeBindable = HitObject.StartTimeBindable.GetBoundCopy();
+ startTimeBindable.BindValueChanged(_ => ApplyDefaultsToHitObject(), true);
}
///
@@ -81,9 +83,6 @@ namespace osu.Game.Rulesets.Edit
PlacementActive = false;
}
- [Resolved(canBeNull: true)]
- private IFrameBasedClock editorClock { get; set; }
-
///
/// Updates the position of this to a new screen-space position.
///
@@ -91,7 +90,7 @@ namespace osu.Game.Rulesets.Edit
public virtual void UpdatePosition(SnapResult snapResult)
{
if (!PlacementActive)
- HitObject.StartTime = snapResult.Time ?? editorClock?.CurrentTime ?? Time.Current;
+ HitObject.StartTime = snapResult.Time ?? EditorClock?.CurrentTime ?? Time.Current;
}
///
diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs
index 897c6ec531..59b3d1c565 100644
--- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs
+++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs
@@ -13,7 +13,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
-using osu.Framework.Timing;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
@@ -26,7 +25,7 @@ namespace osu.Game.Screens.Edit.Components
private IconButton playButton;
[Resolved]
- private IAdjustableClock adjustableClock { get; set; }
+ private EditorClock editorClock { get; set; }
private readonly BindableNumber tempo = new BindableDouble(1);
@@ -87,17 +86,17 @@ namespace osu.Game.Screens.Edit.Components
private void togglePause()
{
- if (adjustableClock.IsRunning)
- adjustableClock.Stop();
+ if (editorClock.IsRunning)
+ editorClock.Stop();
else
- adjustableClock.Start();
+ editorClock.Start();
}
protected override void Update()
{
base.Update();
- playButton.Icon = adjustableClock.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle;
+ playButton.Icon = editorClock.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle;
}
private class PlaybackTabControl : OsuTabControl
diff --git a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs
index 4bf21d240a..c1f54d7938 100644
--- a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs
+++ b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs
@@ -5,7 +5,6 @@ using osu.Framework.Graphics;
using osu.Game.Graphics.Sprites;
using System;
using osu.Framework.Allocation;
-using osu.Framework.Timing;
using osu.Game.Graphics;
namespace osu.Game.Screens.Edit.Components
@@ -15,7 +14,7 @@ namespace osu.Game.Screens.Edit.Components
private readonly OsuSpriteText trackTimer;
[Resolved]
- private IAdjustableClock adjustableClock { get; set; }
+ private EditorClock editorClock { get; set; }
public TimeInfoContainer()
{
@@ -35,7 +34,7 @@ namespace osu.Game.Screens.Edit.Components
{
base.Update();
- trackTimer.Text = TimeSpan.FromMilliseconds(adjustableClock.CurrentTime).ToString(@"mm\:ss\:fff");
+ trackTimer.Text = TimeSpan.FromMilliseconds(editorClock.CurrentTime).ToString(@"mm\:ss\:fff");
}
}
}
diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs
index 5d638d7919..9e9ac93d23 100644
--- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs
+++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs
@@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Framework.Threading;
-using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
@@ -20,14 +19,14 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
///
public class MarkerPart : TimelinePart
{
- private readonly Drawable marker;
+ private Drawable marker;
- private readonly IAdjustableClock adjustableClock;
+ [Resolved]
+ private EditorClock editorClock { get; set; }
- public MarkerPart(IAdjustableClock adjustableClock)
+ [BackgroundDependencyLoader]
+ private void load()
{
- this.adjustableClock = adjustableClock;
-
Add(marker = new MarkerVisualisation());
}
@@ -59,14 +58,14 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
return;
float markerPos = Math.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth);
- adjustableClock.Seek(markerPos / DrawWidth * Beatmap.Value.Track.Length);
+ editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength);
});
}
protected override void Update()
{
base.Update();
- marker.X = (float)adjustableClock.CurrentTime;
+ marker.X = (float)editorClock.CurrentTime;
}
protected override void LoadBeatmap(WorkingBeatmap beatmap)
diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs
index 20db2cac21..02cd4bccb4 100644
--- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs
+++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs
@@ -6,7 +6,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Timing;
using osu.Game.Graphics;
using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts;
@@ -18,11 +17,11 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary
public class SummaryTimeline : BottomBarContainer
{
[BackgroundDependencyLoader]
- private void load(OsuColour colours, IAdjustableClock adjustableClock)
+ private void load(OsuColour colours)
{
Children = new Drawable[]
{
- new MarkerPart(adjustableClock) { RelativeSizeAxes = Axes.Both },
+ new MarkerPart { RelativeSizeAxes = Axes.Both },
new ControlPointPart
{
Anchor = Anchor.Centre,
diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
index e38df3d812..cc417bbb10 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
-using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
@@ -14,7 +13,6 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
-using osu.Framework.Timing;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
@@ -29,8 +27,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
///
public abstract class BlueprintContainer : CompositeDrawable, IKeyBindingHandler
{
- public event Action> SelectionChanged;
-
protected DragBox DragBox { get; private set; }
protected Container SelectionBlueprints { get; private set; }
@@ -41,7 +37,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private IEditorChangeHandler changeHandler { get; set; }
[Resolved]
- private IAdjustableClock adjustableClock { get; set; }
+ private EditorClock editorClock { get; set; }
[Resolved]
private EditorBeatmap beatmap { get; set; }
@@ -88,8 +84,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect();
break;
}
-
- SelectionChanged?.Invoke(selectedHitObjects);
};
}
@@ -149,7 +143,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
if (clickedBlueprint == null)
return false;
- adjustableClock?.Seek(clickedBlueprint.HitObject.StartTime);
+ editorClock?.SeekTo(clickedBlueprint.HitObject.StartTime);
return true;
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs
index 61ed1743a9..717d60b4f3 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs
@@ -9,7 +9,6 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Audio;
using osu.Framework.Input.Events;
-using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Edit;
@@ -25,7 +24,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
public readonly IBindable Beatmap = new Bindable();
[Resolved]
- private IAdjustableClock adjustableClock { get; set; }
+ private EditorClock editorClock { get; set; }
public Timeline()
{
@@ -101,7 +100,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 };
// This needs to happen after transforms are updated, but before the scroll position is updated in base.UpdateAfterChildren
- if (adjustableClock.IsRunning)
+ if (editorClock.IsRunning)
scrollToTrackTime();
}
@@ -111,21 +110,21 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
if (handlingDragInput)
seekTrackToCurrent();
- else if (!adjustableClock.IsRunning)
+ else if (!editorClock.IsRunning)
{
// The track isn't running. There are two cases we have to be wary of:
// 1) The user flick-drags on this timeline: We want the track to follow us
// 2) The user changes the track time through some other means (scrolling in the editor or overview timeline): We want to follow the track time
// The simplest way to cover both cases is by checking whether the scroll position has changed and the audio hasn't been changed externally
- if (Current != lastScrollPosition && adjustableClock.CurrentTime == lastTrackTime)
+ if (Current != lastScrollPosition && editorClock.CurrentTime == lastTrackTime)
seekTrackToCurrent();
else
scrollToTrackTime();
}
lastScrollPosition = Current;
- lastTrackTime = adjustableClock.CurrentTime;
+ lastTrackTime = editorClock.CurrentTime;
}
private void seekTrackToCurrent()
@@ -133,7 +132,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
if (!track.IsLoaded)
return;
- adjustableClock.Seek(Current / Content.DrawWidth * track.Length);
+ editorClock.Seek(Current / Content.DrawWidth * track.Length);
}
private void scrollToTrackTime()
@@ -141,7 +140,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
if (!track.IsLoaded || track.Length == 0)
return;
- ScrollTo((float)(adjustableClock.CurrentTime / track.Length) * Content.DrawWidth, false);
+ ScrollTo((float)(editorClock.CurrentTime / track.Length) * Content.DrawWidth, false);
}
protected override bool OnMouseDown(MouseDownEvent e)
@@ -164,15 +163,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
private void beginUserDrag()
{
handlingDragInput = true;
- trackWasPlaying = adjustableClock.IsRunning;
- adjustableClock.Stop();
+ trackWasPlaying = editorClock.IsRunning;
+ editorClock.Stop();
}
private void endUserDrag()
{
handlingDragInput = false;
if (trackWasPlaying)
- adjustableClock.Start();
+ editorClock.Start();
}
[Resolved]
diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs
index 54e4af94a4..9f61589c36 100644
--- a/osu.Game/Screens/Edit/Editor.cs
+++ b/osu.Game/Screens/Edit/Editor.cs
@@ -83,8 +83,8 @@ namespace osu.Game.Screens.Edit
clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false };
clock.ChangeSource(sourceClock);
- dependencies.CacheAs(clock);
- dependencies.CacheAs(clock);
+ dependencies.CacheAs(clock);
+ AddInternal(clock);
// todo: remove caching of this and consume via editorBeatmap?
dependencies.Cache(beatDivisor);
diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs
index e5e47507f3..dd934c10cd 100644
--- a/osu.Game/Screens/Edit/EditorClock.cs
+++ b/osu.Game/Screens/Edit/EditorClock.cs
@@ -3,6 +3,8 @@
using System;
using System.Linq;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Transforms;
using osu.Framework.Utils;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
@@ -13,7 +15,7 @@ namespace osu.Game.Screens.Edit
///
/// A decoupled clock which adds editor-specific functionality, such as snapping to a user-defined beat divisor.
///
- public class EditorClock : DecoupleableInterpolatingFramedClock
+ public class EditorClock : Component, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock
{
public readonly double TrackLength;
@@ -21,12 +23,11 @@ namespace osu.Game.Screens.Edit
private readonly BindableBeatDivisor beatDivisor;
- public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor)
- {
- this.beatDivisor = beatDivisor;
+ private readonly DecoupleableInterpolatingFramedClock underlyingClock;
- ControlPointInfo = beatmap.Beatmap.ControlPointInfo;
- TrackLength = beatmap.Track.Length;
+ public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor)
+ : this(beatmap.Beatmap.ControlPointInfo, beatmap.Track.Length, beatDivisor)
+ {
}
public EditorClock(ControlPointInfo controlPointInfo, double trackLength, BindableBeatDivisor beatDivisor)
@@ -35,6 +36,13 @@ namespace osu.Game.Screens.Edit
ControlPointInfo = controlPointInfo;
TrackLength = trackLength;
+
+ underlyingClock = new DecoupleableInterpolatingFramedClock();
+ }
+
+ public EditorClock()
+ : this(new ControlPointInfo(), 1000, new BindableBeatDivisor())
+ {
}
///
@@ -79,20 +87,22 @@ namespace osu.Game.Screens.Edit
private void seek(int direction, bool snapped, double amount = 1)
{
+ double current = CurrentTimeAccurate;
+
if (amount <= 0) throw new ArgumentException("Value should be greater than zero", nameof(amount));
- var timingPoint = ControlPointInfo.TimingPointAt(CurrentTime);
+ var timingPoint = ControlPointInfo.TimingPointAt(current);
- if (direction < 0 && timingPoint.Time == CurrentTime)
+ if (direction < 0 && timingPoint.Time == current)
// When going backwards and we're at the boundary of two timing points, we compute the seek distance with the timing point which we are seeking into
- timingPoint = ControlPointInfo.TimingPointAt(CurrentTime - 1);
+ timingPoint = ControlPointInfo.TimingPointAt(current - 1);
double seekAmount = timingPoint.BeatLength / beatDivisor.Value * amount;
- double seekTime = CurrentTime + seekAmount * direction;
+ double seekTime = current + seekAmount * direction;
if (!snapped || ControlPointInfo.TimingPoints.Count == 0)
{
- Seek(seekTime);
+ SeekTo(seekTime);
return;
}
@@ -110,7 +120,7 @@ namespace osu.Game.Screens.Edit
// Due to the rounding above, we may end up on the current beat. This will effectively cause 0 seeking to happen, but we don't want this.
// Instead, we'll go to the next beat in the direction when this is the case
- if (Precision.AlmostEquals(CurrentTime, seekTime))
+ if (Precision.AlmostEquals(current, seekTime))
{
closestBeat += direction > 0 ? 1 : -1;
seekTime = timingPoint.Time + closestBeat * seekAmount;
@@ -125,7 +135,97 @@ namespace osu.Game.Screens.Edit
// Ensure the sought point is within the boundaries
seekTime = Math.Clamp(seekTime, 0, TrackLength);
- Seek(seekTime);
+ SeekTo(seekTime);
+ }
+
+ ///
+ /// The current time of this clock, include any active transform seeks performed via .
+ ///
+ public double CurrentTimeAccurate =>
+ Transforms.OfType().FirstOrDefault()?.EndValue ?? CurrentTime;
+
+ public double CurrentTime => underlyingClock.CurrentTime;
+
+ public void Reset()
+ {
+ ClearTransforms();
+ underlyingClock.Reset();
+ }
+
+ public void Start()
+ {
+ ClearTransforms();
+ underlyingClock.Start();
+ }
+
+ public void Stop()
+ {
+ underlyingClock.Stop();
+ }
+
+ public bool Seek(double position)
+ {
+ ClearTransforms();
+ return underlyingClock.Seek(position);
+ }
+
+ public void ResetSpeedAdjustments() => underlyingClock.ResetSpeedAdjustments();
+
+ double IAdjustableClock.Rate
+ {
+ get => underlyingClock.Rate;
+ set => underlyingClock.Rate = value;
+ }
+
+ double IClock.Rate => underlyingClock.Rate;
+
+ public bool IsRunning => underlyingClock.IsRunning;
+
+ public void ProcessFrame() => underlyingClock.ProcessFrame();
+
+ public double ElapsedFrameTime => underlyingClock.ElapsedFrameTime;
+
+ public double FramesPerSecond => underlyingClock.FramesPerSecond;
+
+ public FrameTimeInfo TimeInfo => underlyingClock.TimeInfo;
+
+ public void ChangeSource(IClock source) => underlyingClock.ChangeSource(source);
+
+ public IClock Source => underlyingClock.Source;
+
+ public bool IsCoupled
+ {
+ get => underlyingClock.IsCoupled;
+ set => underlyingClock.IsCoupled = value;
+ }
+
+ private const double transform_time = 300;
+
+ public void SeekTo(double seekDestination)
+ {
+ if (IsRunning)
+ Seek(seekDestination);
+ else
+ transformSeekTo(seekDestination, transform_time, Easing.OutQuint);
+ }
+
+ private void transformSeekTo(double seek, double duration = 0, Easing easing = Easing.None)
+ => this.TransformTo(this.PopulateTransform(new TransformSeek(), seek, duration, easing));
+
+ private double currentTime
+ {
+ get => underlyingClock.CurrentTime;
+ set => underlyingClock.Seek(value);
+ }
+
+ private class TransformSeek : Transform
+ {
+ public override string TargetMember => nameof(currentTime);
+
+ protected override void Apply(EditorClock clock, double time) =>
+ clock.currentTime = Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing);
+
+ protected override void ReadIntoStartValue(EditorClock clock) => StartValue = clock.currentTime;
}
}
}
diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs
index d9da3ff92d..a08a660e7e 100644
--- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs
+++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs
@@ -7,7 +7,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics;
@@ -23,7 +22,7 @@ namespace osu.Game.Screens.Edit.Timing
private Bindable selectedGroup = new Bindable();
[Resolved]
- private IAdjustableClock clock { get; set; }
+ private EditorClock clock { get; set; }
protected override Drawable CreateMainContent() => new GridContainer
{
@@ -50,7 +49,7 @@ namespace osu.Game.Screens.Edit.Timing
selectedGroup.BindValueChanged(selected =>
{
if (selected.NewValue != null)
- clock.Seek(selected.NewValue.Time);
+ clock.SeekTo(selected.NewValue.Time);
});
}
@@ -62,7 +61,7 @@ namespace osu.Game.Screens.Edit.Timing
private IBindableList controlGroups;
[Resolved]
- private IFrameBasedClock clock { get; set; }
+ private EditorClock clock { get; set; }
[Resolved]
protected IBindable Beatmap { get; private set; }
diff --git a/osu.Game/Skinning/SkinInfo.cs b/osu.Game/Skinning/SkinInfo.cs
index 6b9627188e..b9fe44ef3b 100644
--- a/osu.Game/Skinning/SkinInfo.cs
+++ b/osu.Game/Skinning/SkinInfo.cs
@@ -24,8 +24,6 @@ namespace osu.Game.Skinning
public bool DeletePending { get; set; }
- public string FullName => $"\"{Name}\" by {Creator}";
-
public static SkinInfo Default { get; } = new SkinInfo
{
Name = "osu!lazer",
@@ -34,6 +32,10 @@ namespace osu.Game.Skinning
public bool Equals(SkinInfo other) => other != null && ID == other.ID;
- public override string ToString() => FullName;
+ public override string ToString()
+ {
+ string author = Creator == null ? string.Empty : $"({Creator})";
+ return $"{Name} {author}".Trim();
+ }
}
}
diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs
index 830e6ed363..f0ec638fc9 100644
--- a/osu.Game/Tests/Visual/EditorClockTestScene.cs
+++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs
@@ -30,8 +30,7 @@ namespace osu.Game.Tests.Visual
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.Cache(BeatDivisor);
- dependencies.CacheAs(Clock);
- dependencies.CacheAs(Clock);
+ dependencies.CacheAs(Clock);
return dependencies;
}
diff --git a/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs b/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs
index feecea473c..c3d74f21aa 100644
--- a/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs
+++ b/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs
@@ -8,6 +8,7 @@ using osu.Framework.Timing;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose;
namespace osu.Game.Tests.Visual
@@ -32,7 +33,7 @@ namespace osu.Game.Tests.Visual
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
- dependencies.CacheAs(new StopwatchClock());
+ dependencies.CacheAs(new EditorClock());
return dependencies;
}
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 010ef8578a..d8feb4df24 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -19,7 +19,7 @@
-
+
@@ -27,7 +27,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 88b0c7dd8a..6d74be5f85 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -75,13 +75,13 @@
-
+
-
+