1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 05:53:10 +08:00

Refactor ReplayInputHandler creation for more flexibility.

This commit is contained in:
Dean Herbert 2017-03-31 15:59:53 +09:00
parent 0f4b98ce73
commit fa7c72a099
No known key found for this signature in database
GPG Key ID: 46D71BF4958ABB49
13 changed files with 84 additions and 119 deletions

View File

@ -15,7 +15,7 @@ using osu.Game.Modes.Replays;
namespace osu.Game.Modes.Osu
{
public class OsuAutoReplay : FramedReplay
public class OsuAutoReplay : Replay
{
private static readonly Vector2 spinner_centre = new Vector2(256, 192);

View File

@ -101,7 +101,7 @@ namespace osu.Game.Database
using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize))
using (var reader = new StreamReader(lzma))
score.Replay = score.CreateLegacyReplayFrom(reader);
score.Replay = score.CreateReplay(reader);
}
}

View File

@ -157,7 +157,7 @@ namespace osu.Game.Modes.Mods
public void Apply(HitRenderer<T> hitRenderer)
{
hitRenderer.InputManager.ReplayInputHandler = CreateReplayScore(hitRenderer.Beatmap)?.Replay?.CreateInputHandler();
hitRenderer.SetReplay(CreateReplayScore(hitRenderer.Beatmap)?.Replay);
}
}

View File

@ -1,15 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Game.Input.Handlers;
namespace osu.Game.Modes.Replays
{
public abstract class FramedReplay : Replay
{
protected List<ReplayFrame> Frames = new List<ReplayFrame>();
public override ReplayInputHandler CreateInputHandler() => new FramedReplayInputHandler(Frames);
}
}

View File

@ -1,4 +1,7 @@
using System;
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Input;
@ -17,18 +20,20 @@ namespace osu.Game.Modes.Replays
/// </summary>
public class FramedReplayInputHandler : ReplayInputHandler
{
private readonly List<ReplayFrame> replayContent;
private readonly Replay replay;
public ReplayFrame CurrentFrame => !hasFrames ? null : replayContent[currentFrameIndex];
public ReplayFrame NextFrame => !hasFrames ? null : replayContent[nextFrameIndex];
protected List<ReplayFrame> Frames => replay.Frames;
public ReplayFrame CurrentFrame => !hasFrames ? null : Frames[currentFrameIndex];
public ReplayFrame NextFrame => !hasFrames ? null : Frames[nextFrameIndex];
private int currentFrameIndex;
private int nextFrameIndex => MathHelper.Clamp(currentFrameIndex + (currentDirection > 0 ? 1 : -1), 0, replayContent.Count - 1);
private int nextFrameIndex => MathHelper.Clamp(currentFrameIndex + (currentDirection > 0 ? 1 : -1), 0, Frames.Count - 1);
public FramedReplayInputHandler(List<ReplayFrame> replayContent)
public FramedReplayInputHandler(Replay replay)
{
this.replayContent = replayContent;
this.replay = replay;
}
private bool advanceFrame()
@ -75,7 +80,7 @@ namespace osu.Game.Modes.Replays
};
}
public bool AtLastFrame => currentFrameIndex == replayContent.Count - 1;
public bool AtLastFrame => currentFrameIndex == Frames.Count - 1;
public bool AtFirstFrame => currentFrameIndex == 0;
public Vector2 Size => new Vector2(512, 384);
@ -91,7 +96,7 @@ namespace osu.Game.Modes.Replays
/// </summary>
public bool FrameAccuratePlayback = true;
private bool hasFrames => replayContent.Count > 0;
private bool hasFrames => Frames.Count > 0;
private bool inImportantSection =>
FrameAccuratePlayback &&

View File

@ -1,70 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.IO;
using osu.Game.IO.Legacy;
namespace osu.Game.Modes.Replays
{
/// <summary>
/// Reads a replay from a legacy replay file (.osr v1)
/// </summary>
public class LegacyFramedReplay : FramedReplay
{
public LegacyFramedReplay(StreamReader reader)
{
float lastTime = 0;
foreach (var l in reader.ReadToEnd().Split(','))
{
var split = l.Split('|');
if (split.Length < 4 || float.Parse(split[0]) < 0) continue;
lastTime += float.Parse(split[0]);
Frames.Add(new ReplayFrame(
lastTime,
float.Parse(split[1]),
384 - float.Parse(split[2]),
(ReplayButtonState)int.Parse(split[3])
));
}
}
public class LegacyReplayFrame : ReplayFrame
{
public LegacyReplayFrame(Stream s) : this(new SerializationReader(s))
{
}
public LegacyReplayFrame(SerializationReader sr)
{
ButtonState = (ReplayButtonState)sr.ReadByte();
byte bt = sr.ReadByte();
if (bt > 0)//Handle Pre-Taiko compatible replays.
ButtonState = ReplayButtonState.Right1;
MouseX = sr.ReadSingle();
MouseY = sr.ReadSingle();
Time = sr.ReadInt32();
}
public void ReadFromStream(SerializationReader sr)
{
throw new NotImplementedException();
}
public void WriteToStream(SerializationWriter sw)
{
sw.Write((byte)ButtonState);
sw.Write((byte)0);
sw.Write(MouseX);
sw.Write(MouseY);
sw.Write(Time);
}
}
}
}

View File

@ -1,12 +1,12 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Input.Handlers;
using System.Collections.Generic;
namespace osu.Game.Modes.Replays
{
public abstract class Replay
public class Replay
{
public virtual ReplayInputHandler CreateInputHandler() => null;
public List<ReplayFrame> Frames = new List<ReplayFrame>();
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Database;
using osu.Game.Modes.Mods;
@ -46,11 +47,34 @@ namespace osu.Game.Modes.Scoring
public DateTime Date;
/// <summary>
/// Creates a legacy replay which is read from a stream.
/// Creates a replay which is read from a stream.
/// </summary>
/// <param name="reader">The stream reader.</param>
/// <returns>The replay.</returns>
public virtual Replay CreateLegacyReplayFrom(StreamReader reader) => new LegacyFramedReplay(reader);
public virtual Replay CreateReplay(StreamReader reader)
{
var frames = new List<ReplayFrame>();
float lastTime = 0;
foreach (var l in reader.ReadToEnd().Split(','))
{
var split = l.Split('|');
if (split.Length < 4 || float.Parse(split[0]) < 0) continue;
lastTime += float.Parse(split[0]);
frames.Add(new ReplayFrame(
lastTime,
float.Parse(split[1]),
384 - float.Parse(split[2]),
(ReplayButtonState)int.Parse(split[3])
));
}
return new Replay { Frames = frames };
}
// [JsonProperty(@"count50")] 0,
//[JsonProperty(@"count100")] 0,

View File

@ -14,6 +14,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Game.Modes.Replays;
using osu.Game.Modes.Scoring;
namespace osu.Game.Modes.UI
@ -68,6 +69,10 @@ namespace osu.Game.Modes.UI
/// </summary>
/// <returns>The input manager.</returns>
protected virtual KeyConversionInputManager CreateKeyConversionInputManager() => new KeyConversionInputManager();
protected virtual FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new FramedReplayInputHandler(replay);
public void SetReplay(Replay replay) => InputManager.ReplayInputHandler = CreateReplayInputHandler(replay);
}
/// <summary>

View File

@ -125,7 +125,7 @@ namespace osu.Game
Beatmap.Value = BeatmapDatabase.GetWorkingBeatmap(s.Beatmap);
menu.Push(new PlayerLoader(new Player { ReplayInputHandler = s.Replay.CreateInputHandler() }));
menu.Push(new PlayerLoader(new ReplayPlayer(s.Replay)));
}
protected override void LoadComplete()

View File

@ -15,7 +15,6 @@ using osu.Framework.Screens;
using osu.Framework.Timing;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Input.Handlers;
using osu.Game.Modes;
using osu.Game.Modes.UI;
using osu.Game.Screens.Backgrounds;
@ -34,7 +33,7 @@ namespace osu.Game.Screens.Play
internal override bool HasLocalCursorDisplayed => !hasReplayLoaded && !IsPaused;
private bool hasReplayLoaded => hitRenderer.InputManager.ReplayInputHandler != null;
private bool hasReplayLoaded => HitRenderer.InputManager.ReplayInputHandler != null;
public BeatmapInfo BeatmapInfo;
@ -53,7 +52,7 @@ namespace osu.Game.Screens.Play
private Ruleset ruleset;
private ScoreProcessor scoreProcessor;
private HitRenderer hitRenderer;
protected HitRenderer HitRenderer;
private Bindable<int> dimLevel;
private SkipButton skipButton;
@ -112,9 +111,9 @@ namespace osu.Game.Screens.Play
});
ruleset = Ruleset.GetRuleset(Beatmap.PlayMode);
hitRenderer = ruleset.CreateHitRendererWith(Beatmap);
HitRenderer = ruleset.CreateHitRendererWith(Beatmap);
scoreProcessor = hitRenderer.CreateScoreProcessor();
scoreProcessor = HitRenderer.CreateScoreProcessor();
hudOverlay = new StandardHudOverlay();
hudOverlay.KeyCounter.Add(ruleset.CreateGameplayKeys());
@ -133,13 +132,10 @@ namespace osu.Game.Screens.Play
};
if (ReplayInputHandler != null)
hitRenderer.InputManager.ReplayInputHandler = ReplayInputHandler;
hudOverlay.BindHitRenderer(hitRenderer);
hudOverlay.BindHitRenderer(HitRenderer);
//bind HitRenderer to ScoreProcessor and ourselves (for a pass situation)
hitRenderer.OnAllJudged += onCompletion;
HitRenderer.OnAllJudged += onCompletion;
//bind ScoreProcessor to ourselves (for a fail situation)
scoreProcessor.Failed += onFail;
@ -152,7 +148,7 @@ namespace osu.Game.Screens.Play
Clock = interpolatedSourceClock,
Children = new Drawable[]
{
hitRenderer,
HitRenderer,
skipButton = new SkipButton
{
Alpha = 0
@ -336,8 +332,6 @@ namespace osu.Game.Screens.Play
private Bindable<bool> mouseWheelDisabled;
public ReplayInputHandler ReplayInputHandler;
protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !IsPaused;
}
}

View File

@ -0,0 +1,23 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Replays;
namespace osu.Game.Screens.Play
{
public class ReplayPlayer : Player
{
public Replay Replay;
public ReplayPlayer(Replay replay)
{
Replay = replay;
}
protected override void LoadComplete()
{
base.LoadComplete();
HitRenderer.SetReplay(Replay);
}
}
}

View File

@ -96,10 +96,9 @@
<Compile Include="IO\Legacy\SerializationReader.cs" />
<Compile Include="IO\Legacy\SerializationWriter.cs" />
<Compile Include="IPC\ScoreIPCChannel.cs" />
<Compile Include="Modes\Replays\FramedReplay.cs" />
<Compile Include="Modes\Replays\Replay.cs" />
<Compile Include="Modes\Judgements\DrawableJudgement.cs" />
<Compile Include="Modes\Replays\FramedReplayInputHandler.cs" />
<Compile Include="Modes\Replays\LegacyFramedReplay.cs" />
<Compile Include="Modes\Mods\IApplicableMod.cs" />
<Compile Include="Modes\Mods\ModType.cs" />
<Compile Include="Modes\Objects\Drawables\ArmedState.cs" />
@ -125,7 +124,6 @@
<Compile Include="Modes\Objects\Types\IHasPosition.cs" />
<Compile Include="Modes\Objects\Types\IHasHold.cs" />
<Compile Include="Modes\Objects\Legacy\LegacyHitObjectType.cs" />
<Compile Include="Modes\Replays\Replay.cs" />
<Compile Include="Modes\Replays\ReplayButtonState.cs" />
<Compile Include="Modes\Replays\ReplayFrame.cs" />
<Compile Include="Modes\Scoring\Score.cs" />
@ -202,6 +200,7 @@
<Compile Include="Screens\Play\KeyConversionInputManager.cs" />
<Compile Include="Screens\Play\PlayerInputManager.cs" />
<Compile Include="Screens\Play\PlayerLoader.cs" />
<Compile Include="Screens\Play\ReplayPlayer.cs" />
<Compile Include="Screens\Play\SkipButton.cs" />
<Compile Include="Modes\UI\StandardComboCounter.cs" />
<Compile Include="Screens\Select\BeatmapCarousel.cs" />