mirror of
https://github.com/ppy/osu.git
synced 2024-11-13 16:47:46 +08:00
Simplify parsing code
Less methods, less smeared around logic, saner data types.
This commit is contained in:
parent
c9e8d66e19
commit
0e0ab66148
@ -129,11 +129,6 @@ namespace osu.Game.Localisation
|
||||
/// </summary>
|
||||
public static LocalisableString FailedToProcessTimestamp => new TranslatableString(getKey(@"failed_to_process_timestamp"), @"Failed to process timestamp");
|
||||
|
||||
/// <summary>
|
||||
/// "The timestamp was too long to process"
|
||||
/// </summary>
|
||||
public static LocalisableString TooLongTimestamp => new TranslatableString(getKey(@"too_long_timestamp"), @"The timestamp was too long to process");
|
||||
|
||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit
|
||||
@ -12,26 +11,40 @@ namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
// 00:00:000 (...) - test
|
||||
// original osu-web regex: https://github.com/ppy/osu-web/blob/3b1698639244cfdaf0b41c68bfd651ea729ec2e3/resources/js/utils/beatmapset-discussion-helper.ts#L78
|
||||
public static readonly Regex TIME_REGEX = new Regex(@"\b(((\d{2,}):([0-5]\d)[:.](\d{3}))(\s\([^)]+\))?)");
|
||||
public static readonly Regex TIME_REGEX = new Regex(@"\b(((?<minutes>\d{2,}):(?<seconds>[0-5]\d)[:.](?<milliseconds>\d{3}))(?<selection>\s\([^)]+\))?)", RegexOptions.Compiled);
|
||||
|
||||
public static string[] GetRegexGroups(string timestamp)
|
||||
public static bool TryParse(string timestamp, [NotNullWhen(true)] out TimeSpan? parsedTime, out string? parsedSelection)
|
||||
{
|
||||
Match match = TIME_REGEX.Match(timestamp);
|
||||
|
||||
string[] result = match.Success
|
||||
? match.Groups.Values.Where(x => x is not Match && !x.Value.Contains(':')).Select(x => x.Value).ToArray()
|
||||
: Array.Empty<string>();
|
||||
if (!match.Success)
|
||||
{
|
||||
parsedTime = null;
|
||||
parsedSelection = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
bool result = true;
|
||||
|
||||
public static double GetTotalMilliseconds(params string[] timesGroup)
|
||||
{
|
||||
int[] times = timesGroup.Select(int.Parse).ToArray();
|
||||
result &= int.TryParse(match.Groups[@"minutes"].Value, out int timeMin);
|
||||
result &= int.TryParse(match.Groups[@"seconds"].Value, out int timeSec);
|
||||
result &= int.TryParse(match.Groups[@"milliseconds"].Value, out int timeMsec);
|
||||
|
||||
Debug.Assert(times.Length == 3);
|
||||
// somewhat sane limit for timestamp duration (10 hours).
|
||||
result &= timeMin < 600;
|
||||
|
||||
return (times[0] * 60 + times[1]) * 1000 + times[2];
|
||||
if (!result)
|
||||
{
|
||||
parsedTime = null;
|
||||
parsedSelection = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
parsedTime = TimeSpan.FromMinutes(timeMin) + TimeSpan.FromSeconds(timeSec) + TimeSpan.FromMilliseconds(timeMsec);
|
||||
parsedSelection = match.Groups[@"selection"].Value.Trim();
|
||||
if (!string.IsNullOrEmpty(parsedSelection))
|
||||
parsedSelection = parsedSelection[1..^1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1141,9 +1141,7 @@ namespace osu.Game.Screens.Edit
|
||||
|
||||
public void HandleTimestamp(string timestamp)
|
||||
{
|
||||
string[] groups = EditorTimestampParser.GetRegexGroups(timestamp);
|
||||
|
||||
if (groups.Length != 4 || string.IsNullOrEmpty(groups[0]))
|
||||
if (!EditorTimestampParser.TryParse(timestamp, out var timeSpan, out string selection))
|
||||
{
|
||||
Schedule(() => notifications?.Post(new SimpleNotification
|
||||
{
|
||||
@ -1153,31 +1151,14 @@ namespace osu.Game.Screens.Edit
|
||||
return;
|
||||
}
|
||||
|
||||
string timeMin = groups[0];
|
||||
string timeSec = groups[1];
|
||||
string timeMss = groups[2];
|
||||
string objectsGroup = groups[3].Replace("(", "").Replace(")", "").Trim();
|
||||
|
||||
// Currently, lazer chat highlights infinite-long editor links like `10000000000:00:000 (1)`
|
||||
// Limit timestamp link length at 30000 min (50 hr) to avoid parsing issues
|
||||
if (string.IsNullOrEmpty(timeMin) || timeMin.Length > 5 || double.Parse(timeMin) > 30_000)
|
||||
{
|
||||
Schedule(() => notifications?.Post(new SimpleNotification
|
||||
{
|
||||
Icon = FontAwesome.Solid.ExclamationTriangle,
|
||||
Text = EditorStrings.TooLongTimestamp
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
editorBeatmap.SelectedHitObjects.Clear();
|
||||
|
||||
if (clock.IsRunning)
|
||||
clock.Stop();
|
||||
|
||||
double position = EditorTimestampParser.GetTotalMilliseconds(timeMin, timeSec, timeMss);
|
||||
double position = timeSpan.Value.TotalMilliseconds;
|
||||
|
||||
if (string.IsNullOrEmpty(objectsGroup))
|
||||
if (string.IsNullOrEmpty(selection))
|
||||
{
|
||||
clock.SeekSmoothlyTo(position);
|
||||
return;
|
||||
@ -1194,8 +1175,8 @@ namespace osu.Game.Screens.Edit
|
||||
if (Mode.Value != EditorScreenMode.Compose)
|
||||
Mode.Value = EditorScreenMode.Compose;
|
||||
|
||||
// Let the Ruleset handle selection
|
||||
currentScreen.Dependencies.Get<HitObjectComposer>().SelectHitObjects(position, objectsGroup);
|
||||
// Delegate handling the selection to the ruleset.
|
||||
currentScreen.Dependencies.Get<HitObjectComposer>().SelectHitObjects(position, selection);
|
||||
}
|
||||
|
||||
public double SnapTime(double time, double? referenceTime) => editorBeatmap.SnapTime(time, referenceTime);
|
||||
|
Loading…
Reference in New Issue
Block a user