mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-25 22:18:34 +01:00
Compare commits
4 commits
cc749103e0
...
5906278091
Author | SHA1 | Date | |
---|---|---|---|
5906278091 | |||
8bb62a2ce5 | |||
797a3b2617 | |||
8469185297 |
4 changed files with 198 additions and 27 deletions
|
@ -15,6 +15,7 @@ Jump to version:
|
|||
Additions
|
||||
- Added TokenizedString.Realign
|
||||
- Added GetFlags and GetUniqueFlags to EnumHelper
|
||||
- Added GetDownTime, GetUpTime, GetTimeSincePress, WasModifierDown and WasDown to Keybind and Combination
|
||||
- **Added the ability to find paths to one of multiple goals using AStar**
|
||||
|
||||
Improvements
|
||||
|
@ -25,6 +26,7 @@ Improvements
|
|||
- Allow retrieving the cost of a calculated path when using AStar
|
||||
- Added trimming and AOT annotations and made MLEM trimmable
|
||||
- Allow specifying percentage-based padding for a NinePatch
|
||||
- Improved the way InputHandler down time calculation works
|
||||
- **Drastically improved StaticSpriteBatch batching performance**
|
||||
- **Made GenericFont and TokenizedString support UTF-32 characters like emoji**
|
||||
|
||||
|
@ -32,6 +34,7 @@ Fixes
|
|||
- Fixed TokenizedString handling trailing spaces incorrectly in the last line of non-left aligned text
|
||||
- Fixed some TokenizedString tokens starting with a line break not being split correctly
|
||||
- Fixed InputHandler maintaining old input states when input types are toggled off
|
||||
- Fixed Combination.IsModifierDown querying one of its modifiers instead of all of them
|
||||
|
||||
Removals
|
||||
- Marked EnumHelper as obsolete due to its reimplementation in [DynamicEnums](https://www.nuget.org/packages/DynamicEnums)
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace MLEM.Input {
|
|||
public static readonly Buttons[] AllButtons =
|
||||
#if NET6_0_OR_GREATER
|
||||
Enum.GetValues<Buttons>();
|
||||
#else
|
||||
#else
|
||||
(Buttons[]) Enum.GetValues(typeof(Buttons));
|
||||
#endif
|
||||
/// <summary>
|
||||
|
@ -29,7 +29,7 @@ namespace MLEM.Input {
|
|||
public static readonly Keys[] AllKeys =
|
||||
#if NET6_0_OR_GREATER
|
||||
Enum.GetValues<Keys>();
|
||||
#else
|
||||
#else
|
||||
(Keys[]) Enum.GetValues(typeof(Keys));
|
||||
#endif
|
||||
|
||||
|
@ -179,6 +179,7 @@ namespace MLEM.Input {
|
|||
private readonly List<GestureSample> gestures = new List<GestureSample>();
|
||||
private readonly HashSet<(GenericInput, int)> consumedPresses = new HashSet<(GenericInput, int)>();
|
||||
private readonly Dictionary<(GenericInput, int), DateTime> inputUpTimes = new Dictionary<(GenericInput, int), DateTime>();
|
||||
private readonly Dictionary<(GenericInput, int), DateTime> inputDownTimes = new Dictionary<(GenericInput, int), DateTime>();
|
||||
private readonly Dictionary<(GenericInput, int), DateTime> inputPressedTimes = new Dictionary<(GenericInput, int), DateTime>();
|
||||
|
||||
private Point ViewportOffset => new Point(-this.Game.GraphicsDevice.Viewport.X, -this.Game.GraphicsDevice.Viewport.Y);
|
||||
|
@ -356,13 +357,15 @@ namespace MLEM.Input {
|
|||
}
|
||||
this.InputsPressed = pressed.ToArray();
|
||||
|
||||
// handle inputs that changed to up
|
||||
foreach (var key in this.inputsDownAccum.Keys)
|
||||
this.inputUpTimes.Remove(key);
|
||||
// handle inputs that changed between down and up
|
||||
foreach (var key in this.inputsDown.Keys) {
|
||||
if (!this.inputsDownAccum.ContainsKey(key))
|
||||
this.inputUpTimes[key] = DateTime.UtcNow;
|
||||
}
|
||||
foreach (var key in this.inputsDownAccum.Keys) {
|
||||
if (!this.inputsDown.ContainsKey(key))
|
||||
this.inputDownTimes[key] = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
// handle inputs that are currently down
|
||||
this.InputsDown = this.inputsDownAccum.Keys.Select(key => key.Item1).ToArray();
|
||||
|
@ -754,6 +757,48 @@ namespace MLEM.Input {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a given control of any kind was down in the last update call.
|
||||
/// This is a helper function that can be passed a <see cref="Keys"/>, <see cref="Buttons"/> or <see cref="MouseButton"/>.
|
||||
/// </summary>
|
||||
/// <param name="control">The control whose down state to query</param>
|
||||
/// <param name="index">The index of the gamepad to query (if applicable), or -1 for any gamepad</param>
|
||||
/// <returns>Whether the given control was down</returns>
|
||||
/// <exception cref="ArgumentException">If the passed control isn't of a supported type</exception>
|
||||
public bool WasDown(GenericInput control, int index = -1) {
|
||||
switch (control.Type) {
|
||||
case GenericInput.InputType.Keyboard:
|
||||
return this.WasKeyDown(control);
|
||||
case GenericInput.InputType.Gamepad:
|
||||
return this.WasGamepadButtonDown(control, index);
|
||||
case GenericInput.InputType.Mouse:
|
||||
return this.WasMouseButtonDown(control);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a given control of any kind was up in the last update call.
|
||||
/// This is a helper function that can be passed a <see cref="Keys"/>, <see cref="Buttons"/> or <see cref="MouseButton"/>.
|
||||
/// </summary>
|
||||
/// <param name="control">The control whose up state to query</param>
|
||||
/// <param name="index">The index of the gamepad to query (if applicable), or -1 for any gamepad</param>
|
||||
/// <returns>Whether the given control was up.</returns>
|
||||
/// <exception cref="ArgumentException">If the passed control isn't of a supported type</exception>
|
||||
public bool WasUp(GenericInput control, int index = -1) {
|
||||
switch (control.Type) {
|
||||
case GenericInput.InputType.Keyboard:
|
||||
return this.WasKeyUp(control);
|
||||
case GenericInput.InputType.Gamepad:
|
||||
return this.WasGamepadButtonUp(control, index);
|
||||
case GenericInput.InputType.Mouse:
|
||||
return this.WasMouseButtonUp(control);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a given control of any kind is pressed.
|
||||
/// This is a helper function that can be passed a <see cref="Keys"/>, <see cref="Buttons"/> or <see cref="MouseButton"/>.
|
||||
|
@ -852,15 +897,17 @@ namespace MLEM.Input {
|
|||
|
||||
/// <summary>
|
||||
/// Tries to retrieve the amount of time that a given <see cref="GenericInput"/> has been held down for.
|
||||
/// If the input is currently down, this method returns true and the amount of time that it has been down for is stored in <paramref name="downTime"/>.
|
||||
/// If the input is currently down or has been down previously, this method returns true and the amount of time that it has currently or last been down for is stored in <paramref name="downTime"/>.
|
||||
/// </summary>
|
||||
/// <param name="input">The input whose down time to query.</param>
|
||||
/// <param name="downTime">The resulting down time, or <see cref="TimeSpan.Zero"/> if the input is not being held.</param>
|
||||
/// <param name="index">The index of the gamepad to query (if applicable), or -1 for any gamepad.</param>
|
||||
/// <returns>Whether the input is currently being held.</returns>
|
||||
public bool TryGetDownTime(GenericInput input, out TimeSpan downTime, int index = -1) {
|
||||
if (this.inputsDown.TryGetValue((input, index), out var start)) {
|
||||
downTime = DateTime.UtcNow - start;
|
||||
if (this.inputDownTimes.TryGetValue((input, index), out var wentDown)) {
|
||||
// if we're currently down, we return the amount of time we've been down for so far
|
||||
// if we're not currently down, we return the last amount of time we were down for
|
||||
downTime = (this.IsDown(input) || !this.inputUpTimes.TryGetValue((input, index), out var wentUp) ? DateTime.UtcNow : wentUp) - wentDown;
|
||||
return true;
|
||||
}
|
||||
downTime = default;
|
||||
|
@ -868,8 +915,8 @@ namespace MLEM.Input {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the amount of time that a given <see cref="GenericInput"/> has been held down for.
|
||||
/// If this input isn't currently down, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// Returns the current or last amount of time that a given <see cref="GenericInput"/> has been held down for.
|
||||
/// If this input isn't currently down and has not been down previously, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// </summary>
|
||||
/// <param name="input">The input whose down time to query.</param>
|
||||
/// <param name="index">The index of the gamepad to query (if applicable), or -1 for any gamepad.</param>
|
||||
|
@ -881,15 +928,17 @@ namespace MLEM.Input {
|
|||
|
||||
/// <summary>
|
||||
/// Tries to retrieve the amount of time that a given <see cref="GenericInput"/> has been up for since the last time it was down.
|
||||
/// If the input is currently up, this method returns true and the amount of time that it has been up for is stored in <paramref name="upTime"/>.
|
||||
/// If the input has previously been down, this method returns true and the amount of time that it has been up for is stored in <paramref name="upTime"/>.
|
||||
/// </summary>
|
||||
/// <param name="input">The input whose up time to query.</param>
|
||||
/// <param name="upTime">The resulting up time, or <see cref="TimeSpan.Zero"/> if the input is being held.</param>
|
||||
/// <param name="index">The index of the gamepad to query (if applicable), or -1 for any gamepad.</param>
|
||||
/// <returns>Whether the input is currently up.</returns>
|
||||
public bool TryGetUpTime(GenericInput input, out TimeSpan upTime, int index = -1) {
|
||||
if (this.inputUpTimes.TryGetValue((input, index), out var start)) {
|
||||
upTime = DateTime.UtcNow - start;
|
||||
if (this.inputUpTimes.TryGetValue((input, index), out var wentUp)) {
|
||||
// if we're currently up, we return the amount of time we've been up for so far
|
||||
// if we're not currently up, we return the last amount of time we were up for
|
||||
upTime = (this.IsUp(input) || !this.inputDownTimes.TryGetValue((input, index), out var wentDown) ? DateTime.UtcNow : wentDown) - wentUp;
|
||||
return true;
|
||||
}
|
||||
upTime = default;
|
||||
|
@ -897,8 +946,8 @@ namespace MLEM.Input {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the amount of time that a given <see cref="GenericInput"/> has been up for since the last time it was down.
|
||||
/// If this input isn't currently up, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// Returns the amount of time that a given <see cref="GenericInput"/> has last been up for since the last time it was down.
|
||||
/// If this input hasn't been down previously, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// </summary>
|
||||
/// <param name="input">The input whose up time to query.</param>
|
||||
/// <param name="index">The index of the gamepad to query (if applicable), or -1 for any gamepad.</param>
|
||||
|
@ -927,7 +976,7 @@ namespace MLEM.Input {
|
|||
|
||||
/// <summary>
|
||||
/// Returns the amount of time that has passed since a given <see cref="GenericInput"/> last counted as pressed.
|
||||
/// If this input hasn't been pressed previously, or is currently pressed, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// If this input hasn't been pressed previously, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// </summary>
|
||||
/// <param name="input">The input whose up time to query.</param>
|
||||
/// <param name="index">The index of the gamepad to query (if applicable), or -1 for any gamepad.</param>
|
||||
|
|
|
@ -123,6 +123,21 @@ namespace MLEM.Input {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this keybind was considered to be down in the last update call.
|
||||
/// See <see cref="InputHandler.WasDown"/> for more information.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>Whether this keybind was considered to be down</returns>
|
||||
public bool WasDown(InputHandler handler, int gamepadIndex = -1) {
|
||||
foreach (var combination in this.combinations) {
|
||||
if (combination.WasDown(handler, gamepadIndex))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this keybind is considered to be pressed.
|
||||
/// See <see cref="InputHandler.IsPressed"/> for more information.
|
||||
|
@ -183,6 +198,54 @@ namespace MLEM.Input {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether any of this keybind's modifier keys were down in the last update call.
|
||||
/// See <see cref="InputHandler.WasDown"/> for more information.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>Whether any of this keyboard's modifier keys were down</returns>
|
||||
public bool WasModifierDown(InputHandler handler, int gamepadIndex = -1) {
|
||||
foreach (var combination in this.combinations) {
|
||||
if (combination.WasModifierDown(handler, gamepadIndex))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the amount of time that this keybind has been held down for.
|
||||
/// If this input isn't currently down, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>The resulting down time, or <see cref="TimeSpan.Zero"/> if the input is not being held.</returns>
|
||||
public TimeSpan GetDownTime(InputHandler handler, int gamepadIndex = -1) {
|
||||
return this.combinations.Max(c => c.GetDownTime(handler, gamepadIndex));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the amount of time that this keybind has been up for since the last time it was down.
|
||||
/// If this input isn't currently up, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>The resulting up time, or <see cref="TimeSpan.Zero"/> if the input is being held.</returns>
|
||||
public TimeSpan GetUpTime(InputHandler handler, int gamepadIndex = -1) {
|
||||
return this.combinations.Min(c => c.GetUpTime(handler, gamepadIndex));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the amount of time that has passed since this keybind last counted as pressed.
|
||||
/// If this input hasn't been pressed previously, or is currently pressed, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>The resulting up time, or <see cref="TimeSpan.Zero"/> if the input has never been pressed, or is currently pressed.</returns>
|
||||
public TimeSpan GetTimeSincePress(InputHandler handler, int gamepadIndex = -1) {
|
||||
return this.combinations.Min(c => c.GetTimeSincePress(handler, gamepadIndex));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerable of all of the combinations that this keybind currently contains
|
||||
/// </summary>
|
||||
|
@ -287,7 +350,7 @@ namespace MLEM.Input {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this combination is currently down
|
||||
/// Returns whether this combination is currently down.
|
||||
/// See <see cref="InputHandler.IsDown"/> for more information.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
|
@ -297,6 +360,17 @@ namespace MLEM.Input {
|
|||
return this.IsModifierDown(handler, gamepadIndex) && handler.IsDown(this.Key, gamepadIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this combination was down in the last upate call.
|
||||
/// See <see cref="InputHandler.WasDown"/> for more information.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>Whether this combination was down</returns>
|
||||
public bool WasDown(InputHandler handler, int gamepadIndex = -1) {
|
||||
return this.WasModifierDown(handler, gamepadIndex) && handler.WasDown(this.Key, gamepadIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this combination is currently pressed.
|
||||
/// See <see cref="InputHandler.IsPressed"/> for more information.
|
||||
|
@ -332,19 +406,64 @@ namespace MLEM.Input {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this combination's modifier keys are currently down
|
||||
/// Returns whether all of this combination's modifier keys are currently down.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>Whether this combination's modifiers are down</returns>
|
||||
public bool IsModifierDown(InputHandler handler, int gamepadIndex = -1) {
|
||||
if (this.Modifiers.Length <= 0)
|
||||
return true;
|
||||
foreach (var modifier in this.Modifiers) {
|
||||
if (handler.IsDown(modifier, gamepadIndex))
|
||||
return true;
|
||||
if (!handler.IsDown(modifier, gamepadIndex))
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether all of this combination's modifier keys were down in the last update call.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>Whether this combination's modifiers were down</returns>
|
||||
public bool WasModifierDown(InputHandler handler, int gamepadIndex = -1) {
|
||||
foreach (var modifier in this.Modifiers) {
|
||||
if (!handler.WasDown(modifier, gamepadIndex))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the amount of time that this combination has been held down for.
|
||||
/// If this input isn't currently down, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>The resulting down time, or <see cref="TimeSpan.Zero"/> if the input is not being held.</returns>
|
||||
public TimeSpan GetDownTime(InputHandler handler, int gamepadIndex = -1) {
|
||||
return handler.GetDownTime(this.Key, gamepadIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the amount of time that this combination has been up for since the last time it was down.
|
||||
/// If this input isn't currently up, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>The resulting up time, or <see cref="TimeSpan.Zero"/> if the input is being held.</returns>
|
||||
public TimeSpan GetUpTime(InputHandler handler, int gamepadIndex = -1) {
|
||||
return handler.GetUpTime(this.Key, gamepadIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the amount of time that has passed since this combination last counted as pressed.
|
||||
/// If this input hasn't been pressed previously, or is currently pressed, this method returns <see cref="TimeSpan.Zero"/>.
|
||||
/// </summary>
|
||||
/// <param name="handler">The input handler to query the keys with</param>
|
||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
||||
/// <returns>The resulting up time, or <see cref="TimeSpan.Zero"/> if the input has never been pressed, or is currently pressed.</returns>
|
||||
public TimeSpan GetTimeSincePress(InputHandler handler, int gamepadIndex = -1) {
|
||||
return handler.GetTimeSincePress(this.Key, gamepadIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -397,12 +397,12 @@ public class GameImpl : MlemGame {
|
|||
|
||||
/*if (Input.InputsDown.Length > 0)
|
||||
Console.WriteLine("Down: " + string.Join(", ", Input.InputsDown));*/
|
||||
/*if (MlemGame.Input.InputsPressed.Length > 0)
|
||||
if (MlemGame.Input.InputsPressed.Length > 0)
|
||||
Console.WriteLine("Pressed: " + string.Join(", ", MlemGame.Input.InputsPressed));
|
||||
MlemGame.Input.HandleKeyboardRepeats = false;
|
||||
MlemGame.Input.HandleKeyboardRepeats = false;/*
|
||||
Console.WriteLine("Down time: " + MlemGame.Input.GetDownTime(Keys.A));
|
||||
Console.WriteLine("Time since press: " + MlemGame.Input.GetTimeSincePress(Keys.A));
|
||||
Console.WriteLine("Up time: " + MlemGame.Input.GetUpTime(Keys.A));*/
|
||||
Console.WriteLine("Time since press: " + MlemGame.Input.GetTimeSincePress(Keys.A));*/
|
||||
Console.WriteLine("Up time: " + MlemGame.Input.GetUpTime(Keys.A));
|
||||
}
|
||||
|
||||
protected override void DoDraw(GameTime gameTime) {
|
||||
|
|
Loading…
Reference in a new issue