// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osuTK; namespace osu.Game.Tests.Beatmaps { public class TestWorkingBeatmap : WorkingBeatmap { private readonly TrackVirtualManual track; private readonly IBeatmap beatmap; /// /// Create an instance which creates a for the provided ruleset when requested. /// /// The target ruleset. /// A clock which should be used instead of a stopwatch for virtual time progression. public TestWorkingBeatmap(RulesetInfo ruleset, IFrameBasedClock referenceClock) : this(new TestBeatmap(ruleset), referenceClock) { } /// /// Create an instance which provides the when requested. /// /// The beatmap /// An optional clock which should be used instead of a stopwatch for virtual time progression. public TestWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock referenceClock = null) : base(beatmap.BeatmapInfo) { this.beatmap = beatmap; if (referenceClock != null) track = new TrackVirtualManual(referenceClock); } protected override IBeatmap GetBeatmap() => beatmap; protected override Texture GetBackground() => null; protected override Track GetTrack() => track; /// /// A virtual track which tracks a reference clock. /// public class TrackVirtualManual : Track { private readonly IFrameBasedClock referenceClock; private readonly ManualClock clock; private bool running; private double offset; public TrackVirtualManual(IFrameBasedClock referenceClock) { this.referenceClock = referenceClock; Length = double.PositiveInfinity; clock = new ManualClock(); } public override bool Seek(double seek) { offset = MathHelper.Clamp(seek, 0, Length) - referenceClock.CurrentTime; return true; } public override void Start() { running = true; Seek(0); } public override void Reset() { Seek(0); base.Reset(); } public override void Stop() { running = false; } public override bool IsRunning => running; public override double CurrentTime => running ? clock.CurrentTime : 0; protected override void UpdateState() { base.UpdateState(); clock.CurrentTime = Math.Min(referenceClock.CurrentTime + offset, Length); if (CurrentTime >= Length) { Stop(); RaiseCompleted(); } } } } }