Skip to content

Commit a873176

Browse files
committed
refactoring and optimizations
1 parent 11d9044 commit a873176

1 file changed

Lines changed: 38 additions & 55 deletions

File tree

Heroes.LocaleText/GameStringParser.cs

Lines changed: 38 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ internal class GameStringParser
1616

1717
private readonly string _description;
1818
private readonly StormLocale _gameStringLocale;
19-
private readonly List<TextRange> _textStack = [];
19+
private readonly List<TextRange> _textStack;
2020

2121
private readonly HashSet<string>? _styleTagVariables;
2222
private readonly HashSet<string>? _styleConstantTagVariables;
@@ -29,14 +29,16 @@ internal class GameStringParser
2929
private Dictionary<string, (string Value, bool Preserve)>.AlternateLookup<ReadOnlySpan<char>>? _valueByStyleConstantVarAltLookup;
3030
#endif
3131

32-
private bool _isContructed = false;
32+
private bool _isConstructed = false;
3333
private int _startingIndex = 0;
3434
private int _index = 0;
3535

3636
private CultureInfo? _culture;
3737

3838
private GameStringParser(string description, StormLocale gameStringLocale, bool extractFontVars)
3939
{
40+
_textStack = new List<TextRange>(description.Length / 10);
41+
4042
_description = description;
4143
_gameStringLocale = gameStringLocale;
4244

@@ -198,7 +200,7 @@ private static bool IsDigits(ReadOnlySpan<char> value)
198200

199201
for (int i = 0; i < value.Length; i++)
200202
{
201-
if (char.IsDigit(value[i]))
203+
if ((uint)(value[i] - '0') <= 9)
202204
continue;
203205
else if (dot is false && value[i] == '.')
204206
dot = true;
@@ -244,10 +246,10 @@ private static void CopyEndTag(Span<char> buffer, ref int offset, ReadOnlySpan<c
244246

245247
private string Parse(ReadOnlySpan<char> gameString)
246248
{
247-
if (!_isContructed)
249+
if (!_isConstructed)
248250
{
249251
ConstructTextStack(gameString);
250-
_isContructed = true;
252+
_isConstructed = true;
251253
}
252254

253255
return BuildDescription(gameString, new GameStringFlags()
@@ -262,10 +264,10 @@ private string Parse(ReadOnlySpan<char> gameString)
262264

263265
private string ParseToPlainText(ReadOnlySpan<char> gameString, bool includeNewlineTags, bool includeScaling)
264266
{
265-
if (!_isContructed)
267+
if (!_isConstructed)
266268
{
267269
ConstructTextStack(gameString);
268-
_isContructed = true;
270+
_isConstructed = true;
269271
}
270272

271273
return BuildDescription(gameString, new GameStringFlags()
@@ -280,10 +282,10 @@ private string ParseToPlainText(ReadOnlySpan<char> gameString, bool includeNewli
280282

281283
private string ParseToColoredText(ReadOnlySpan<char> gameString, bool includeScaling)
282284
{
283-
if (!_isContructed)
285+
if (!_isConstructed)
284286
{
285287
ConstructTextStack(gameString);
286-
_isContructed = true;
288+
_isConstructed = true;
287289
}
288290

289291
return BuildDescription(gameString, new GameStringFlags()
@@ -305,7 +307,7 @@ private string BuildDescription(ReadOnlySpan<char> gameString, GameStringFlags f
305307

306308
Span<char> buffer = totalSize < 1024 ? stackalloc char[totalSize] : new char[totalSize];
307309

308-
ReadOnlySpan<char> startTag = null;
310+
ReadOnlySpan<char> startTag = [];
309311
int currentOffset = 0;
310312

311313
// loop through and build string
@@ -346,7 +348,7 @@ private string BuildDescription(ReadOnlySpan<char> gameString, GameStringFlags f
346348
else
347349
{
348350
// dont save, empty tag
349-
startTag = null;
351+
startTag = [];
350352
}
351353
}
352354

@@ -358,7 +360,7 @@ private string BuildDescription(ReadOnlySpan<char> gameString, GameStringFlags f
358360
if (!FontValueCopiedInBuffer(buffer, startTag, ref currentOffset))
359361
CopyIntoBuffer(buffer, ref currentOffset, startTag, true);
360362

361-
startTag = null;
363+
startTag = [];
362364
}
363365

364366
if (flags.ScalingTag == TagFlag.Eval && double.TryParse(itemText.Trim('~'), CultureInfo.InvariantCulture, out double scaleValue))
@@ -385,7 +387,7 @@ private string BuildDescription(ReadOnlySpan<char> gameString, GameStringFlags f
385387
if (!FontValueCopiedInBuffer(buffer, startTag, ref currentOffset))
386388
CopyIntoBuffer(buffer, ref currentOffset, startTag, true);
387389

388-
startTag = null;
390+
startTag = [];
389391
CopyIntoBuffer(buffer, ref currentOffset, itemText, false);
390392
}
391393
else if (item.Type == TextType.ErrorTag)
@@ -402,7 +404,7 @@ private string BuildDescription(ReadOnlySpan<char> gameString, GameStringFlags f
402404
}
403405
}
404406

405-
// remove any null chars at the end
407+
// slice, so no null chars the end
406408
return buffer[..currentOffset].ToString();
407409
}
408410

@@ -579,35 +581,18 @@ private void ConstructTextStack(ReadOnlySpan<char> gameString, Range? startTag =
579581
}
580582
}
581583

584+
private void PushNormalText(
582585
#if DEBUG
583-
private void PushNormalText(ReadOnlySpan<char> gameString, bool append = false)
586+
ReadOnlySpan<char> gameString,
587+
#endif
588+
bool append = false)
584589
{
585590
int normalTextLength = _index - _startingIndex;
586591
if (normalTextLength > 0)
587592
{
593+
#if DEBUG
588594
ReadOnlySpan<char> temp = gameString.Slice(_startingIndex, normalTextLength);
589-
590-
if (append is false)
591-
{
592-
_textStack.Add(new TextRange(new Range(_startingIndex, _index), TextType.Text));
593-
}
594-
else
595-
{
596-
int lastIndex = _textStack.Count - 1;
597-
598-
Range existing = _textStack[lastIndex].Range;
599-
600-
_textStack.RemoveAt(lastIndex);
601-
_textStack.Add(new TextRange(new Range(existing.Start, _index), TextType.Text));
602-
}
603-
}
604-
}
605-
#else
606-
private void PushNormalText(bool append = false)
607-
{
608-
int normalTextLength = _index - _startingIndex;
609-
if (normalTextLength > 0)
610-
{
595+
#endif
611596
if (append is false)
612597
{
613598
_textStack.Add(new TextRange(new Range(_startingIndex, _index), TextType.Text));
@@ -618,12 +603,10 @@ private void PushNormalText(bool append = false)
618603

619604
Range existing = _textStack[lastIndex].Range;
620605

621-
_textStack.RemoveAt(lastIndex);
622-
_textStack.Add(new TextRange(new Range(existing.Start, _index), TextType.Text));
606+
_textStack[lastIndex] = new TextRange(new Range(existing.Start, _index), TextType.Text);
623607
}
624608
}
625609
}
626-
#endif
627610

628611
// try to parse out a tag
629612
private bool TryParseTag(ReadOnlySpan<char> gameString, [NotNullWhen(true)] out Range? tag, out bool isStartTag)
@@ -684,18 +667,9 @@ private bool TryParseScalingTag(ReadOnlySpan<char> gameString, [NotNullWhen(true
684667
int lengthOffset = gameString.Length - currentTextSpan.Length;
685668

686669
int startScaleIndex = currentTextSpan.IndexOf("~~") + 1; // the second char of the ~~ (first batch)
687-
int endScaleIndex = -1; // first char of the ~~ (second batch)
688-
689-
for (int i = startScaleIndex; i < currentTextSpan.Length; i++)
690-
{
691-
// find next occurrence of ~~
692-
if (currentTextSpan[i] == '~' && i + 1 < currentTextSpan.Length && currentTextSpan[i + 1] == '~')
693-
{
694-
endScaleIndex = i;
695-
696-
break;
697-
}
698-
}
670+
int endScaleIndex = currentTextSpan[(startScaleIndex + 1)..].IndexOf("~~"); // first char of the ~~ (second batch)
671+
if (endScaleIndex >= 0)
672+
endScaleIndex += startScaleIndex + 1;
699673

700674
if (startScaleIndex > 0 && endScaleIndex > 0)
701675
{
@@ -752,8 +726,17 @@ private bool TryGetEndTag(ReadOnlySpan<char> gameString, Range startTag, [NotNul
752726

753727
for (int i = 0; i <= currentTextSpan.Length - searchLength; i++)
754728
{
755-
if (currentTextSpan[i] == '<' &&
756-
currentTextSpan[i + 1] == '/' &&
729+
int next = currentTextSpan[i..].IndexOf('<');
730+
731+
if (next < 0)
732+
break;
733+
734+
i += next;
735+
736+
if (i > currentTextSpan.Length - searchLength)
737+
break;
738+
739+
if (currentTextSpan[i + 1] == '/' &&
757740
currentTextSpan[i + searchLength - 1] == '>' &&
758741
currentTextSpan.Slice(i + 2, tagTypeSpan.Length).Equals(tagTypeSpan, StringComparison.OrdinalIgnoreCase))
759742
{
@@ -1020,7 +1003,7 @@ private void GetScalingLocaleText(Span<char> buffer, ref int offset, double valu
10201003
StormLocale.ZHCN => " (每级+0.##%)",
10211004
StormLocale.ZHTW => " (每級+0.##%)",
10221005

1023-
_ => $"{value.ToString(" (+0.##% per level)", _culture)}",
1006+
_ => " (+0.##% per level)",
10241007
};
10251008

10261009
value.TryFormat(buffer[offset..], out int charsWritten, format, _culture);

0 commit comments

Comments
 (0)