1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 01:43:15 +08:00

Update KeyCounterCollection to support action-based buttons

This commit is contained in:
Dean Herbert 2017-08-21 12:31:21 +09:00
parent aa5afc30ef
commit 16e96888ab
23 changed files with 140 additions and 65 deletions

View File

@ -8,6 +8,7 @@ using osu.Desktop.Tests.Beatmaps;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Beatmaps;
@ -77,6 +78,8 @@ namespace osu.Desktop.Tests.Visual
public override ScoreProcessor CreateScoreProcessor() => new TestScoreProcessor();
public override PassThroughInputManager CreateInputManager() => new PassThroughInputManager();
protected override BeatmapConverter<TestHitObject> CreateBeatmapConverter() => new TestBeatmapConverter();
protected override Playfield<TestHitObject, TestJudgement> CreatePlayfield() => new TestPlayfield(scrollingAxes);

View File

@ -3,11 +3,11 @@
using System.ComponentModel;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Catch
{
public class CatchInputManager : DatabasedKeyBindingInputManager<CatchAction>
public class CatchInputManager : RulesetInputManager<CatchAction>
{
public CatchInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique)

View File

@ -1,14 +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 OpenTK.Input;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.Mods;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Catch.Scoring;
@ -101,13 +99,6 @@ namespace osu.Game.Rulesets.Catch
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };
public override IEnumerable<KeyCounter> CreateGameplayKeys() => new KeyCounter[]
{
new KeyCounterKeyboard(Key.ShiftLeft),
new KeyCounterMouse(MouseButton.Left),
new KeyCounterMouse(MouseButton.Right)
};
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new CatchDifficultyCalculator(beatmap);
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor();

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.UI
protected override Playfield<CatchBaseHit, CatchJudgement> CreatePlayfield() => new CatchPlayfield();
public override PassThroughInputManager CreateKeyBindingInputManager() => new CatchInputManager(Ruleset?.RulesetInfo);
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
protected override DrawableHitObject<CatchBaseHit, CatchJudgement> GetVisualRepresentation(CatchBaseHit h)
{

View File

@ -0,0 +1,21 @@
// 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.Framework.Input.Bindings;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Mania
{
public class ManiaInputManager : RulesetInputManager<ManiaAction>
{
public ManiaInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique)
{
}
}
public enum ManiaAction
{
// placeholder
}
}

View File

@ -6,7 +6,6 @@ using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Graphics;
@ -111,8 +110,6 @@ namespace osu.Game.Rulesets.Mania
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };
public override IEnumerable<KeyCounter> CreateGameplayKeys() => new KeyCounter[] { /* Todo: Should be keymod specific */ };
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new ManiaDifficultyCalculator(beatmap);
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor();

View File

@ -10,6 +10,7 @@ using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Lists;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
@ -92,6 +93,8 @@ namespace osu.Game.Rulesets.Mania.UI
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo);
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter() => new ManiaBeatmapConverter();
protected override DrawableHitObject<ManiaHitObject, ManiaJudgement> GetVisualRepresentation(ManiaHitObject h)

View File

@ -79,6 +79,7 @@
<Compile Include="Objects\ManiaHitObject.cs" />
<Compile Include="Objects\Note.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ManiaInputManager.cs" />
<Compile Include="Timing\GravityScrollingContainer.cs" />
<Compile Include="Timing\ScrollingAlgorithm.cs" />
<Compile Include="UI\Column.cs" />

View File

@ -3,11 +3,11 @@
using System.ComponentModel;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Osu
{
public class OsuInputManager : DatabasedKeyBindingInputManager<OsuAction>
public class OsuInputManager : RulesetInputManager<OsuAction>
{
public OsuInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique)
{

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Input;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mods;
@ -10,7 +9,6 @@ using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.OsuDifficulty;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
@ -122,14 +120,6 @@ namespace osu.Game.Rulesets.Osu
public override string Description => "osu!";
public override IEnumerable<KeyCounter> CreateGameplayKeys() => new KeyCounter[]
{
new KeyCounterKeyboard(Key.Z),
new KeyCounterKeyboard(Key.X),
new KeyCounterMouse(MouseButton.Left),
new KeyCounterMouse(MouseButton.Right)
};
public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor();
public override SettingsSubsection CreateSettings() => new OsuSettings();

View File

@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.UI
protected override Playfield<OsuHitObject, OsuJudgement> CreatePlayfield() => new OsuPlayfield();
public override PassThroughInputManager CreateKeyBindingInputManager() => new OsuInputManager(Ruleset?.RulesetInfo);
public override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo);
protected override DrawableHitObject<OsuHitObject, OsuJudgement> GetVisualRepresentation(OsuHitObject h)
{

View File

@ -3,11 +3,11 @@
using System.ComponentModel;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Taiko
{
public class TaikoInputManager : DatabasedKeyBindingInputManager<TaikoAction>
public class TaikoInputManager : RulesetInputManager<TaikoAction>
{
public TaikoInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique)

View File

@ -1,14 +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 OpenTK.Input;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Taiko.Mods;
using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Scoring;
@ -103,14 +101,6 @@ namespace osu.Game.Rulesets.Taiko
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o };
public override IEnumerable<KeyCounter> CreateGameplayKeys() => new KeyCounter[]
{
new KeyCounterKeyboard(Key.D),
new KeyCounterKeyboard(Key.F),
new KeyCounterKeyboard(Key.J),
new KeyCounterKeyboard(Key.K)
};
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new TaikoDifficultyCalculator(beatmap);
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor();

View File

@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Taiko.UI
protected override BeatmapConverter<TaikoHitObject> CreateBeatmapConverter() => new TaikoBeatmapConverter();
public override PassThroughInputManager CreateKeyBindingInputManager() => new TaikoInputManager(Ruleset?.RulesetInfo);
public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo);
protected override Playfield<TaikoHitObject, TaikoJudgement> CreatePlayfield() => new TaikoPlayfield
{

View File

@ -10,7 +10,6 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
namespace osu.Game.Beatmaps
{
@ -76,8 +75,6 @@ namespace osu.Game.Beatmaps
public override string Description => "dummy";
public override IEnumerable<KeyCounter> CreateGameplayKeys() => new List<KeyCounter>();
public DummyRuleset(RulesetInfo rulesetInfo)
: base(rulesetInfo)
{

View File

@ -5,7 +5,6 @@ using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
@ -46,8 +45,6 @@ namespace osu.Game.Rulesets
public abstract string Description { get; }
public abstract IEnumerable<KeyCounter> CreateGameplayKeys();
public virtual SettingsSubsection CreateSettings() => null;
/// <summary>

View File

@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.UI
/// <summary>
/// The key conversion input manager for this RulesetContainer.
/// </summary>
protected readonly PassThroughInputManager KeyConversionInputManager;
public readonly PassThroughInputManager KeyBindingInputManager;
/// <summary>
/// Whether we are currently providing the local user a gameplay cursor.
@ -76,8 +76,10 @@ namespace osu.Game.Rulesets.UI
internal RulesetContainer(Ruleset ruleset)
{
Ruleset = ruleset;
KeyConversionInputManager = CreateKeyBindingInputManager();
KeyConversionInputManager.RelativeSizeAxes = Axes.Both;
KeyBindingInputManager = CreateInputManager();
if (!(KeyBindingInputManager is ICanAttachKeyCounter))
throw new InvalidOperationException($"Rulesets should create input managers of type {nameof(ICanAttachKeyCounter)}");
KeyBindingInputManager.RelativeSizeAxes = Axes.Both;
}
/// <summary>
@ -92,10 +94,10 @@ namespace osu.Game.Rulesets.UI
public abstract ScoreProcessor CreateScoreProcessor();
/// <summary>
/// Creates a key conversion input manager.
/// Creates a key conversion input manager. An exception will be thrown if a valid <see cref="RulesetInputManager{T}"/> is not returned.
/// </summary>
/// <returns>The input manager.</returns>
public virtual PassThroughInputManager CreateKeyBindingInputManager() => new PassThroughInputManager();
public abstract PassThroughInputManager CreateInputManager();
protected virtual FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new FramedReplayInputHandler(replay);
@ -253,7 +255,7 @@ namespace osu.Game.Rulesets.UI
InputManager.Add(content = new Container
{
RelativeSizeAxes = Axes.Both,
Children = new[] { KeyConversionInputManager }
Children = new[] { KeyBindingInputManager }
});
AddInternal(InputManager);
@ -262,7 +264,7 @@ namespace osu.Game.Rulesets.UI
[BackgroundDependencyLoader]
private void load()
{
KeyConversionInputManager.Add(Playfield = CreatePlayfield());
KeyBindingInputManager.Add(Playfield = CreatePlayfield());
loadObjects();

View File

@ -0,0 +1,44 @@
// 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.Linq;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
using osu.Game.Screens.Play;
namespace osu.Game.Rulesets.UI
{
public abstract class RulesetInputManager<T> : DatabasedKeyBindingInputManager<T>, ICanAttachKeyCounter
where T : struct
{
protected RulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) : base(ruleset, variant, unique)
{
}
public void Attach(KeyCounterCollection keyCounter)
{
var receptor = new ActionReceptor(keyCounter);
Add(receptor);
keyCounter.SetReceptor(receptor);
keyCounter.AddRange(DefaultKeyBindings.Select(b => b.GetAction<T>()).Distinct().Select(b => new KeyCounterAction<T>(b)));
}
public class ActionReceptor : KeyCounterCollection.Receptor, IKeyBindingHandler<T>
{
public ActionReceptor(KeyCounterCollection target)
: base(target)
{
}
public bool OnPressed(T action) => Target.Children.OfType<KeyCounterAction<T>>().Any(c => c.OnPressed(action));
public bool OnReleased(T action) => Target.Children.OfType<KeyCounterAction<T>>().Any(c => c.OnReleased(action));
}
}
public interface ICanAttachKeyCounter
{
void Attach(KeyCounterCollection keyCounter);
}
}

View File

@ -92,7 +92,7 @@ namespace osu.Game.Screens.Play
public virtual void BindRulesetContainer(RulesetContainer rulesetContainer)
{
rulesetContainer.InputManager.Add(KeyCounter.GetReceptor());
(rulesetContainer.KeyBindingInputManager as ICanAttachKeyCounter)?.Attach(KeyCounter);
replayLoaded = rulesetContainer.HasReplayLoaded;

View File

@ -0,0 +1,30 @@
// 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.Framework.Input.Bindings;
namespace osu.Game.Screens.Play
{
public class KeyCounterAction<T> : KeyCounter, IKeyBindingHandler<T>
where T : struct
{
public T Action { get; }
public KeyCounterAction(T action) : base($"B{(int)(object)action + 1}")
{
Action = action;
}
public bool OnPressed(T action)
{
if (action.Equals(Action)) IsLit = true;
return false;
}
public bool OnReleased(T action)
{
if (action.Equals(Action)) IsLit = false;
return false;
}
}
}

View File

@ -1,6 +1,7 @@
// 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.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -117,27 +118,36 @@ namespace osu.Game.Screens.Play
return receptor ?? (receptor = new Receptor(this));
}
public void SetReceptor(Receptor receptor)
{
if (this.receptor != null)
throw new InvalidOperationException("Cannot set a new receptor when one is already active");
this.receptor = receptor;
}
public class Receptor : Drawable
{
private readonly KeyCounterCollection target;
protected readonly KeyCounterCollection Target;
public Receptor(KeyCounterCollection target)
{
RelativeSizeAxes = Axes.Both;
this.target = target;
Depth = float.MinValue;
Target = target;
}
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true;
public override bool HandleInput => true;
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => target.Children.Any(c => c.TriggerOnKeyDown(state, args));
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => Target.Children.Any(c => c.TriggerOnKeyDown(state, args));
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => target.Children.Any(c => c.TriggerOnKeyUp(state, args));
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => Target.Children.Any(c => c.TriggerOnKeyUp(state, args));
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => target.Children.Any(c => c.TriggerOnMouseDown(state, args));
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => Target.Children.Any(c => c.TriggerOnMouseDown(state, args));
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => target.Children.Any(c => c.TriggerOnMouseUp(state, args));
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => Target.Children.Any(c => c.TriggerOnMouseUp(state, args));
}
}
}

View File

@ -76,8 +76,6 @@ namespace osu.Game.Screens.Play
sampleRestart = audio.Sample.Get(@"Gameplay/restart");
Ruleset rulesetInstance;
WorkingBeatmap working = Beatmap.Value;
Beatmap beatmap;
@ -89,7 +87,7 @@ namespace osu.Game.Screens.Play
throw new InvalidOperationException("Beatmap was not loaded");
ruleset = osu?.Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset;
rulesetInstance = ruleset.CreateInstance();
var rulesetInstance = ruleset.CreateInstance();
try
{
@ -192,7 +190,6 @@ namespace osu.Game.Screens.Play
scoreProcessor = RulesetContainer.CreateScoreProcessor();
hudOverlay.KeyCounter.AddRange(rulesetInstance.CreateGameplayKeys());
hudOverlay.BindProcessor(scoreProcessor);
hudOverlay.BindRulesetContainer(RulesetContainer);

View File

@ -128,6 +128,8 @@
<Compile Include="Overlays\Profile\Sections\RecentSection.cs" />
<Compile Include="Graphics\Containers\ConstrainedIconContainer.cs" />
<Compile Include="Rulesets\Mods\IApplicableToDifficulty.cs" />
<Compile Include="Rulesets\UI\RulesetInputManager.cs" />
<Compile Include="Screens\Play\KeyCounterAction.cs" />
<Compile Include="Users\UserCoverBackground.cs" />
<Compile Include="Overlays\UserProfileOverlay.cs" />
<Compile Include="Overlays\Profile\ProfileHeader.cs" />