Optimize string memory usage. Use Spans and StringBuilders where possible (#3933)
* Optimize string memory usage. Use ReadOnlySpan<char> and StringBuilder where possible. * Fix copypaste error * Code generator review fixes * Use if statement instead of switch * Code style fixes Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com> * Another code style fix * Styling fix Co-authored-by: Mary-nyan <thog@protonmail.com> * Styling fix Co-authored-by: gdkchan <gab.dark.100@gmail.com> Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com> Co-authored-by: Mary-nyan <thog@protonmail.com> Co-authored-by: gdkchan <gab.dark.100@gmail.com>
This commit is contained in:
parent
f449895e6d
commit
ae4324032a
19 changed files with 118 additions and 81 deletions
|
@ -1339,7 +1339,7 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
private static void SetT32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
|
private static void SetT32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
|
||||||
{
|
{
|
||||||
string reversedEncoding = encoding.Substring(16) + encoding.Substring(0, 16);
|
string reversedEncoding = $"{encoding.AsSpan(16)}{encoding.AsSpan(0, 16)}";
|
||||||
MakeOp reversedMakeOp =
|
MakeOp reversedMakeOp =
|
||||||
(inst, address, opCode)
|
(inst, address, opCode)
|
||||||
=> makeOp(inst, address, (int)BitOperations.RotateRight((uint)opCode, 16));
|
=> makeOp(inst, address, (int)BitOperations.RotateRight((uint)opCode, 16));
|
||||||
|
@ -1353,7 +1353,7 @@ namespace ARMeilleure.Decoders
|
||||||
string thumbEncoding = encoding;
|
string thumbEncoding = encoding;
|
||||||
if (thumbEncoding.StartsWith("<<<<"))
|
if (thumbEncoding.StartsWith("<<<<"))
|
||||||
{
|
{
|
||||||
thumbEncoding = "1110" + thumbEncoding.Substring(4);
|
thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}";
|
||||||
}
|
}
|
||||||
SetT32(thumbEncoding, name, emitter, makeOpT32);
|
SetT32(thumbEncoding, name, emitter, makeOpT32);
|
||||||
}
|
}
|
||||||
|
@ -1365,19 +1365,19 @@ namespace ARMeilleure.Decoders
|
||||||
string thumbEncoding = encoding;
|
string thumbEncoding = encoding;
|
||||||
if (thumbEncoding.StartsWith("11110100"))
|
if (thumbEncoding.StartsWith("11110100"))
|
||||||
{
|
{
|
||||||
thumbEncoding = "11111001" + encoding.Substring(8);
|
thumbEncoding = $"11111001{encoding.AsSpan(8)}";
|
||||||
}
|
}
|
||||||
else if (thumbEncoding.StartsWith("1111001x"))
|
else if (thumbEncoding.StartsWith("1111001x"))
|
||||||
{
|
{
|
||||||
thumbEncoding = "111x1111" + encoding.Substring(8);
|
thumbEncoding = $"111x1111{encoding.AsSpan(8)}";
|
||||||
}
|
}
|
||||||
else if (thumbEncoding.StartsWith("11110010"))
|
else if (thumbEncoding.StartsWith("11110010"))
|
||||||
{
|
{
|
||||||
thumbEncoding = "11101111" + encoding.Substring(8);
|
thumbEncoding = $"11101111{encoding.AsSpan(8)}";
|
||||||
}
|
}
|
||||||
else if (thumbEncoding.StartsWith("11110011"))
|
else if (thumbEncoding.StartsWith("11110011"))
|
||||||
{
|
{
|
||||||
thumbEncoding = "11111111" + encoding.Substring(8);
|
thumbEncoding = $"11111111{encoding.AsSpan(8)}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -183,8 +183,8 @@ namespace ARMeilleure.Translation.PTC
|
||||||
|
|
||||||
private void PreLoad()
|
private void PreLoad()
|
||||||
{
|
{
|
||||||
string fileNameActual = string.Concat(CachePathActual, ".cache");
|
string fileNameActual = $"{CachePathActual}.cache";
|
||||||
string fileNameBackup = string.Concat(CachePathBackup, ".cache");
|
string fileNameBackup = $"{CachePathBackup}.cache";
|
||||||
|
|
||||||
FileInfo fileInfoActual = new FileInfo(fileNameActual);
|
FileInfo fileInfoActual = new FileInfo(fileNameActual);
|
||||||
FileInfo fileInfoBackup = new FileInfo(fileNameBackup);
|
FileInfo fileInfoBackup = new FileInfo(fileNameBackup);
|
||||||
|
@ -400,8 +400,8 @@ namespace ARMeilleure.Translation.PTC
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string fileNameActual = string.Concat(CachePathActual, ".cache");
|
string fileNameActual = $"{CachePathActual}.cache";
|
||||||
string fileNameBackup = string.Concat(CachePathBackup, ".cache");
|
string fileNameBackup = $"{CachePathBackup}.cache";
|
||||||
|
|
||||||
FileInfo fileInfoActual = new FileInfo(fileNameActual);
|
FileInfo fileInfoActual = new FileInfo(fileNameActual);
|
||||||
|
|
||||||
|
|
|
@ -125,8 +125,8 @@ namespace ARMeilleure.Translation.PTC
|
||||||
{
|
{
|
||||||
_lastHash = default;
|
_lastHash = default;
|
||||||
|
|
||||||
string fileNameActual = string.Concat(_ptc.CachePathActual, ".info");
|
string fileNameActual = $"{_ptc.CachePathActual}.info";
|
||||||
string fileNameBackup = string.Concat(_ptc.CachePathBackup, ".info");
|
string fileNameBackup = $"{_ptc.CachePathBackup}.info";
|
||||||
|
|
||||||
FileInfo fileInfoActual = new FileInfo(fileNameActual);
|
FileInfo fileInfoActual = new FileInfo(fileNameActual);
|
||||||
FileInfo fileInfoBackup = new FileInfo(fileNameBackup);
|
FileInfo fileInfoBackup = new FileInfo(fileNameBackup);
|
||||||
|
@ -246,8 +246,8 @@ namespace ARMeilleure.Translation.PTC
|
||||||
{
|
{
|
||||||
_waitEvent.Reset();
|
_waitEvent.Reset();
|
||||||
|
|
||||||
string fileNameActual = string.Concat(_ptc.CachePathActual, ".info");
|
string fileNameActual = $"{_ptc.CachePathActual}.info";
|
||||||
string fileNameBackup = string.Concat(_ptc.CachePathBackup, ".info");
|
string fileNameBackup = $"{_ptc.CachePathBackup}.info";
|
||||||
|
|
||||||
FileInfo fileInfoActual = new FileInfo(fileNameActual);
|
FileInfo fileInfoActual = new FileInfo(fileNameActual);
|
||||||
|
|
||||||
|
|
|
@ -435,7 +435,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
||||||
if (str.Length > MaxSize)
|
if (str.Length > MaxSize)
|
||||||
{
|
{
|
||||||
return str.Substring(0, MaxSize - Ellipsis.Length) + Ellipsis;
|
return $"{str.AsSpan(0, MaxSize - Ellipsis.Length)}{Ellipsis}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Utilities
|
namespace Ryujinx.Common.Utilities
|
||||||
{
|
{
|
||||||
|
@ -6,7 +7,7 @@ namespace Ryujinx.Common.Utilities
|
||||||
{
|
{
|
||||||
public static UInt128 FromHex(string hex)
|
public static UInt128 FromHex(string hex)
|
||||||
{
|
{
|
||||||
return new UInt128((ulong)Convert.ToInt64(hex.Substring(0, 16), 16), (ulong)Convert.ToInt64(hex.Substring(16), 16));
|
return new UInt128(ulong.Parse(hex.AsSpan(0, 16), NumberStyles.HexNumber), ulong.Parse(hex.AsSpan(16), NumberStyles.HexNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UInt128 CreateRandom()
|
public static UInt128 CreateRandom()
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
||||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||||
|
@ -44,11 +45,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||||
|
|
||||||
string texCall;
|
var texCallBuilder = new StringBuilder();
|
||||||
|
|
||||||
if (texOp.Inst == Instruction.ImageAtomic)
|
if (texOp.Inst == Instruction.ImageAtomic)
|
||||||
{
|
{
|
||||||
texCall = (texOp.Flags & TextureFlags.AtomicMask) switch {
|
texCallBuilder.Append((texOp.Flags & TextureFlags.AtomicMask) switch {
|
||||||
TextureFlags.Add => "imageAtomicAdd",
|
TextureFlags.Add => "imageAtomicAdd",
|
||||||
TextureFlags.Minimum => "imageAtomicMin",
|
TextureFlags.Minimum => "imageAtomicMin",
|
||||||
TextureFlags.Maximum => "imageAtomicMax",
|
TextureFlags.Maximum => "imageAtomicMax",
|
||||||
|
@ -60,11 +61,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
TextureFlags.Swap => "imageAtomicExchange",
|
TextureFlags.Swap => "imageAtomicExchange",
|
||||||
TextureFlags.CAS => "imageAtomicCompSwap",
|
TextureFlags.CAS => "imageAtomicCompSwap",
|
||||||
_ => "imageAtomicAdd",
|
_ => "imageAtomicAdd",
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
texCall = texOp.Inst == Instruction.ImageLoad ? "imageLoad" : "imageStore";
|
texCallBuilder.Append(texOp.Inst == Instruction.ImageLoad ? "imageLoad" : "imageStore");
|
||||||
}
|
}
|
||||||
|
|
||||||
int srcIndex = isBindless ? 1 : 0;
|
int srcIndex = isBindless ? 1 : 0;
|
||||||
|
@ -83,7 +84,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
|
|
||||||
string imageName = OperandManager.GetImageName(context.Config.Stage, texOp, indexExpr);
|
string imageName = OperandManager.GetImageName(context.Config.Stage, texOp, indexExpr);
|
||||||
|
|
||||||
texCall += "(" + imageName;
|
texCallBuilder.Append('(');
|
||||||
|
texCallBuilder.Append(imageName);
|
||||||
|
|
||||||
int coordsCount = texOp.Type.GetDimensions();
|
int coordsCount = texOp.Type.GetDimensions();
|
||||||
|
|
||||||
|
@ -91,7 +93,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
|
|
||||||
void Append(string str)
|
void Append(string str)
|
||||||
{
|
{
|
||||||
texCall += ", " + str;
|
texCallBuilder.Append(", ");
|
||||||
|
texCallBuilder.Append(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
string ApplyScaling(string vector)
|
string ApplyScaling(string vector)
|
||||||
|
@ -107,11 +110,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
if (pCount == 3 && isArray)
|
if (pCount == 3 && isArray)
|
||||||
{
|
{
|
||||||
// The array index is not scaled, just x and y.
|
// The array index is not scaled, just x and y.
|
||||||
vector = "ivec3(Helper_TexelFetchScale((" + vector + ").xy, " + scaleIndex + "), (" + vector + ").z)";
|
vector = $"ivec3(Helper_TexelFetchScale(({vector}).xy, {scaleIndex}), ({vector}).z)";
|
||||||
}
|
}
|
||||||
else if (pCount == 2 && !isArray)
|
else if (pCount == 2 && !isArray)
|
||||||
{
|
{
|
||||||
vector = "Helper_TexelFetchScale(" + vector + ", " + scaleIndex + ")";
|
vector = $"Helper_TexelFetchScale({vector}, {scaleIndex})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +130,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
elems[index] = Src(AggregateType.S32);
|
elems[index] = Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
Append(ApplyScaling("ivec" + pCount + "(" + string.Join(", ", elems) + ")"));
|
Append(ApplyScaling($"ivec{pCount}({string.Join(", ", elems)})"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -164,7 +167,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
_ => string.Empty
|
_ => string.Empty
|
||||||
};
|
};
|
||||||
|
|
||||||
Append(prefix + "vec4(" + string.Join(", ", cElems) + ")");
|
Append($"{prefix}vec4({string.Join(", ", cElems)})");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texOp.Inst == Instruction.ImageAtomic)
|
if (texOp.Inst == Instruction.ImageAtomic)
|
||||||
|
@ -185,19 +188,26 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
|
|
||||||
Append(value);
|
Append(value);
|
||||||
|
|
||||||
texCall += ")";
|
texCallBuilder.Append(')');
|
||||||
|
|
||||||
if (type != AggregateType.S32)
|
if (type != AggregateType.S32)
|
||||||
{
|
{
|
||||||
texCall = "int(" + texCall + ")";
|
texCallBuilder
|
||||||
|
.Insert(0, "int(")
|
||||||
|
.Append(')');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
texCall += ")" + (texOp.Inst == Instruction.ImageLoad ? GetMaskMultiDest(texOp.Index) : "");
|
texCallBuilder.Append(')');
|
||||||
|
|
||||||
|
if (texOp.Inst == Instruction.ImageLoad)
|
||||||
|
{
|
||||||
|
texCallBuilder.Append(GetMaskMultiDest(texOp.Index));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return texCall;
|
return texCallBuilder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string LoadAttribute(CodeGenContext context, AstOperation operation)
|
public static string LoadAttribute(CodeGenContext context, AstOperation operation)
|
||||||
|
@ -827,7 +837,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
|
|
||||||
private static string GetMask(int index)
|
private static string GetMask(int index)
|
||||||
{
|
{
|
||||||
return '.' + "rgba".Substring(index, 1);
|
return $".{"rgba".AsSpan(index, 1)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetMaskMultiDest(int mask)
|
private static string GetMaskMultiDest(int mask)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||||
|
using System;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
||||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||||
|
@ -49,7 +50,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
|
|
||||||
private static string GetMask(int index)
|
private static string GetMask(int index)
|
||||||
{
|
{
|
||||||
return '.' + "xy".Substring(index, 1);
|
return $".{"xy".AsSpan(index, 1)}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Graphics.Shader.Instructions;
|
using Ryujinx.Graphics.Shader.Instructions;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Decoders
|
namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
{
|
{
|
||||||
|
@ -329,18 +330,18 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
|
|
||||||
private static void Add(string encoding, InstName name, InstEmitter emitter, InstProps props = InstProps.None)
|
private static void Add(string encoding, InstName name, InstEmitter emitter, InstProps props = InstProps.None)
|
||||||
{
|
{
|
||||||
encoding = encoding.Substring(0, EncodingBits);
|
ReadOnlySpan<char> encodingPart = encoding.AsSpan(0, EncodingBits);
|
||||||
|
|
||||||
int bit = encoding.Length - 1;
|
int bit = encodingPart.Length - 1;
|
||||||
int value = 0;
|
int value = 0;
|
||||||
int xMask = 0;
|
int xMask = 0;
|
||||||
int xBits = 0;
|
int xBits = 0;
|
||||||
|
|
||||||
int[] xPos = new int[encoding.Length];
|
int[] xPos = new int[encodingPart.Length];
|
||||||
|
|
||||||
for (int index = 0; index < encoding.Length; index++, bit--)
|
for (int index = 0; index < encodingPart.Length; index++, bit--)
|
||||||
{
|
{
|
||||||
char chr = encoding[index];
|
char chr = encodingPart[index];
|
||||||
|
|
||||||
if (chr == '1')
|
if (chr == '1')
|
||||||
{
|
{
|
||||||
|
|
|
@ -141,8 +141,8 @@ namespace Ryujinx.HLE.FileSystem
|
||||||
return $"{rawPath}:/";
|
return $"{rawPath}:/";
|
||||||
}
|
}
|
||||||
|
|
||||||
string basePath = rawPath.Substring(0, firstSeparatorOffset);
|
var basePath = rawPath.AsSpan(0, firstSeparatorOffset);
|
||||||
string fileName = rawPath.Substring(firstSeparatorOffset + 1);
|
var fileName = rawPath.AsSpan(firstSeparatorOffset + 1);
|
||||||
|
|
||||||
return $"{basePath}:/{fileName}";
|
return $"{basePath}:/{fileName}";
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||||
for (int maxStr = text.Length; maxStr >= 0; maxStr--)
|
for (int maxStr = text.Length; maxStr >= 0; maxStr--)
|
||||||
{
|
{
|
||||||
// This loop will probably will run only once.
|
// This loop will probably will run only once.
|
||||||
bytes = encoding.GetBytes(text.Substring(0, maxStr));
|
bytes = encoding.GetBytes(text, 0, maxStr);
|
||||||
if (bytes.Length <= maxSize)
|
if (bytes.Length <= maxSize)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -292,20 +292,35 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||||
|
|
||||||
_logoPosition = new Point(logoPositionX, logoPositionY);
|
_logoPosition = new Point(logoPositionX, logoPositionY);
|
||||||
}
|
}
|
||||||
|
private static RectangleF MeasureString(string text, Font font)
|
||||||
private RectangleF MeasureString(string text, Font font)
|
|
||||||
{
|
{
|
||||||
RendererOptions options = new RendererOptions(font);
|
RendererOptions options = new RendererOptions(font);
|
||||||
FontRectangle rectangle = TextMeasurer.Measure(text == "" ? " " : text, options);
|
|
||||||
|
|
||||||
if (text == "")
|
if (text == "")
|
||||||
{
|
{
|
||||||
return new RectangleF(0, rectangle.Y, 0, rectangle.Height);
|
FontRectangle emptyRectangle = TextMeasurer.Measure(" ", options);
|
||||||
|
|
||||||
|
return new RectangleF(0, emptyRectangle.Y, 0, emptyRectangle.Height);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
FontRectangle rectangle = TextMeasurer.Measure(text, options);
|
||||||
|
|
||||||
return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
|
return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static RectangleF MeasureString(ReadOnlySpan<char> text, Font font)
|
||||||
|
{
|
||||||
|
RendererOptions options = new RendererOptions(font);
|
||||||
|
|
||||||
|
if (text == "")
|
||||||
|
{
|
||||||
|
FontRectangle emptyRectangle = TextMeasurer.Measure(" ", options);
|
||||||
|
return new RectangleF(0, emptyRectangle.Y, 0, emptyRectangle.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
FontRectangle rectangle = TextMeasurer.Measure(text, options);
|
||||||
|
|
||||||
|
return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawTextBox(IImageProcessingContext context, SoftwareKeyboardUiState state)
|
private void DrawTextBox(IImageProcessingContext context, SoftwareKeyboardUiState state)
|
||||||
|
@ -354,8 +369,8 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||||
cursorBrush = _selectionBoxBrush;
|
cursorBrush = _selectionBoxBrush;
|
||||||
cursorPen = _selectionBoxPen;
|
cursorPen = _selectionBoxPen;
|
||||||
|
|
||||||
string textUntilBegin = state.InputText.Substring(0, state.CursorBegin);
|
ReadOnlySpan<char> textUntilBegin = state.InputText.AsSpan(0, state.CursorBegin);
|
||||||
string textUntilEnd = state.InputText.Substring(0, state.CursorEnd);
|
ReadOnlySpan<char> textUntilEnd = state.InputText.AsSpan(0, state.CursorEnd);
|
||||||
|
|
||||||
var selectionBeginRectangle = MeasureString(textUntilBegin, _inputTextFont);
|
var selectionBeginRectangle = MeasureString(textUntilBegin, _inputTextFont);
|
||||||
var selectionEndRectangle = MeasureString(textUntilEnd , _inputTextFont);
|
var selectionEndRectangle = MeasureString(textUntilEnd , _inputTextFont);
|
||||||
|
@ -375,7 +390,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||||
// Show the blinking cursor.
|
// Show the blinking cursor.
|
||||||
|
|
||||||
int cursorBegin = Math.Min(state.InputText.Length, state.CursorBegin);
|
int cursorBegin = Math.Min(state.InputText.Length, state.CursorBegin);
|
||||||
string textUntilCursor = state.InputText.Substring(0, cursorBegin);
|
ReadOnlySpan<char> textUntilCursor = state.InputText.AsSpan(0, cursorBegin);
|
||||||
var cursorTextRectangle = MeasureString(textUntilCursor, _inputTextFont);
|
var cursorTextRectangle = MeasureString(textUntilCursor, _inputTextFont);
|
||||||
|
|
||||||
cursorVisible = true;
|
cursorVisible = true;
|
||||||
|
@ -387,7 +402,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||||
|
|
||||||
if (state.CursorBegin < state.InputText.Length)
|
if (state.CursorBegin < state.InputText.Length)
|
||||||
{
|
{
|
||||||
textUntilCursor = state.InputText.Substring(0, cursorBegin + 1);
|
textUntilCursor = state.InputText.AsSpan(0, cursorBegin + 1);
|
||||||
cursorTextRectangle = MeasureString(textUntilCursor, _inputTextFont);
|
cursorTextRectangle = MeasureString(textUntilCursor, _inputTextFont);
|
||||||
cursorPositionXRight = inputTextX + cursorTextRectangle.Width + cursorTextRectangle.X;
|
cursorPositionXRight = inputTextX + cursorTextRectangle.Width + cursorTextRectangle.X;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
|
namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
|
||||||
{
|
{
|
||||||
|
@ -25,7 +26,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
|
||||||
if (_literalValue[0] == 'n')
|
if (_literalValue[0] == 'n')
|
||||||
{
|
{
|
||||||
writer.Write("-");
|
writer.Write("-");
|
||||||
writer.Write(_literalValue.Substring(1));
|
writer.Write(_literalValue.AsSpan(1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,9 +32,9 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
|
||||||
|
|
||||||
private bool ConsumeIf(string toConsume)
|
private bool ConsumeIf(string toConsume)
|
||||||
{
|
{
|
||||||
string mangledPart = Mangled.Substring(_position);
|
var mangledPart = Mangled.AsSpan(_position);
|
||||||
|
|
||||||
if (mangledPart.StartsWith(toConsume))
|
if (mangledPart.StartsWith(toConsume.AsSpan()))
|
||||||
{
|
{
|
||||||
_position += toConsume.Length;
|
_position += toConsume.Length;
|
||||||
|
|
||||||
|
@ -44,14 +44,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string PeekString(int offset = 0, int length = 1)
|
private ReadOnlySpan<char> PeekString(int offset = 0, int length = 1)
|
||||||
{
|
{
|
||||||
if (_position + offset >= length)
|
if (_position + offset >= length)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Mangled.Substring(_position + offset, length);
|
return Mangled.AsSpan(_position + offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private char Peek(int offset = 0)
|
private char Peek(int offset = 0)
|
||||||
|
@ -101,7 +101,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
|
||||||
|
|
||||||
private int ParseSeqId()
|
private int ParseSeqId()
|
||||||
{
|
{
|
||||||
string part = Mangled.Substring(_position);
|
ReadOnlySpan<char> part = Mangled.AsSpan(_position);
|
||||||
int seqIdLen = 0;
|
int seqIdLen = 0;
|
||||||
|
|
||||||
for (; seqIdLen < part.Length; seqIdLen++)
|
for (; seqIdLen < part.Length; seqIdLen++)
|
||||||
|
@ -114,7 +114,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
|
||||||
|
|
||||||
_position += seqIdLen;
|
_position += seqIdLen;
|
||||||
|
|
||||||
return FromBase36(part.Substring(0, seqIdLen));
|
return FromBase36(new string(part[..seqIdLen]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// <substitution> ::= S <seq-id> _
|
// <substitution> ::= S <seq-id> _
|
||||||
|
@ -900,7 +900,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
|
||||||
|
|
||||||
private int ParsePositiveNumber()
|
private int ParsePositiveNumber()
|
||||||
{
|
{
|
||||||
string part = Mangled.Substring(_position);
|
ReadOnlySpan<char> part = Mangled.AsSpan(_position);
|
||||||
int numberLength = 0;
|
int numberLength = 0;
|
||||||
|
|
||||||
for (; numberLength < part.Length; numberLength++)
|
for (; numberLength < part.Length; numberLength++)
|
||||||
|
@ -918,7 +918,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return int.Parse(part.AsSpan(0, numberLength));
|
return int.Parse(part[..numberLength]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ParseNumber(bool isSigned = false)
|
private string ParseNumber(bool isSigned = false)
|
||||||
|
@ -933,7 +933,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string part = Mangled.Substring(_position);
|
ReadOnlySpan<char> part = Mangled.AsSpan(_position);
|
||||||
int numberLength = 0;
|
int numberLength = 0;
|
||||||
|
|
||||||
for (; numberLength < part.Length; numberLength++)
|
for (; numberLength < part.Length; numberLength++)
|
||||||
|
@ -946,7 +946,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
|
||||||
|
|
||||||
_position += numberLength;
|
_position += numberLength;
|
||||||
|
|
||||||
return part.Substring(0, numberLength);
|
return new string(part[..numberLength]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// <source-name> ::= <positive length number> <identifier>
|
// <source-name> ::= <positive length number> <identifier>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using LibHac.Account;
|
using LibHac.Account;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
@ -35,8 +36,8 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
||||||
throw new ArgumentException("Invalid Hex value!", nameof(hex));
|
throw new ArgumentException("Invalid Hex value!", nameof(hex));
|
||||||
}
|
}
|
||||||
|
|
||||||
Low = Convert.ToInt64(hex.Substring(16), 16);
|
Low = long.Parse(hex.AsSpan(16), NumberStyles.HexNumber);
|
||||||
High = Convert.ToInt64(hex.Substring(0, 16), 16);
|
High = long.Parse(hex.AsSpan(0, 16), NumberStyles.HexNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(BinaryWriter binaryWriter)
|
public void Write(BinaryWriter binaryWriter)
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Ryujinx.HLE.Exceptions;
|
||||||
using Ryujinx.HLE.HOS.Services.Settings;
|
using Ryujinx.HLE.HOS.Services.Settings;
|
||||||
using Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager;
|
using Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager;
|
||||||
using Ryujinx.HLE.HOS.Services.Sockets.Nsd.Types;
|
using Ryujinx.HLE.HOS.Services.Sockets.Nsd.Types;
|
||||||
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd
|
namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd
|
||||||
|
@ -370,7 +371,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte environmentType = identifier.Substring(0, 2) switch
|
byte environmentType = identifier.AsSpan(0, 2) switch
|
||||||
{
|
{
|
||||||
"lp" => (byte)ApplicationServerEnvironmentType.Lp,
|
"lp" => (byte)ApplicationServerEnvironmentType.Lp,
|
||||||
"sd" => (byte)ApplicationServerEnvironmentType.Sd,
|
"sd" => (byte)ApplicationServerEnvironmentType.Sd,
|
||||||
|
|
|
@ -4,9 +4,10 @@ namespace Ryujinx.Horizon.Generators
|
||||||
{
|
{
|
||||||
class CodeGenerator
|
class CodeGenerator
|
||||||
{
|
{
|
||||||
private const string Indent = " ";
|
private const int IndentLength = 4;
|
||||||
|
|
||||||
private readonly StringBuilder _sb;
|
private readonly StringBuilder _sb;
|
||||||
private string _currentIndent;
|
private int _currentIndentCount;
|
||||||
|
|
||||||
public CodeGenerator()
|
public CodeGenerator()
|
||||||
{
|
{
|
||||||
|
@ -32,12 +33,15 @@ namespace Ryujinx.Horizon.Generators
|
||||||
|
|
||||||
public void IncreaseIndentation()
|
public void IncreaseIndentation()
|
||||||
{
|
{
|
||||||
_currentIndent += Indent;
|
_currentIndentCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DecreaseIndentation()
|
public void DecreaseIndentation()
|
||||||
{
|
{
|
||||||
_currentIndent = _currentIndent.Substring(0, _currentIndent.Length - Indent.Length);
|
if (_currentIndentCount - 1 >= 0)
|
||||||
|
{
|
||||||
|
_currentIndentCount--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AppendLine()
|
public void AppendLine()
|
||||||
|
@ -47,7 +51,8 @@ namespace Ryujinx.Horizon.Generators
|
||||||
|
|
||||||
public void AppendLine(string text)
|
public void AppendLine(string text)
|
||||||
{
|
{
|
||||||
_sb.AppendLine(_currentIndent + text);
|
_sb.Append(' ', IndentLength * _currentIndentCount);
|
||||||
|
_sb.AppendLine(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
@ -417,7 +417,7 @@ namespace Ryujinx.Horizon.Generators.Kernel
|
||||||
|
|
||||||
private static string GetPrefixedArgName(string name)
|
private static string GetPrefixedArgName(string name)
|
||||||
{
|
{
|
||||||
return ArgVariablePrefix + name[0].ToString().ToUpperInvariant() + name.Substring(1);
|
return ArgVariablePrefix + char.ToUpperInvariant(name[0]) + name.Substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCanonicalTypeName(Compilation compilation, SyntaxNode syntaxNode)
|
private static string GetCanonicalTypeName(Compilation compilation, SyntaxNode syntaxNode)
|
||||||
|
|
|
@ -344,7 +344,7 @@ namespace Ryujinx.Ui.Windows
|
||||||
|
|
||||||
string imageUrl = _amiiboList.FirstOrDefault(amiibo => amiibo.Head + amiibo.Tail == _amiiboCharsComboBox.ActiveId).Image;
|
string imageUrl = _amiiboList.FirstOrDefault(amiibo => amiibo.Head + amiibo.Tail == _amiiboCharsComboBox.ActiveId).Image;
|
||||||
|
|
||||||
string usageString = "";
|
var usageStringBuilder = new StringBuilder();
|
||||||
|
|
||||||
for (int i = 0; i < _amiiboList.Count; i++)
|
for (int i = 0; i < _amiiboList.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -358,19 +358,20 @@ namespace Ryujinx.Ui.Windows
|
||||||
{
|
{
|
||||||
foreach (AmiiboApiUsage usageItem in item.AmiiboUsage)
|
foreach (AmiiboApiUsage usageItem in item.AmiiboUsage)
|
||||||
{
|
{
|
||||||
usageString += Environment.NewLine + $"- {usageItem.Usage.Replace("/", Environment.NewLine + "-")}";
|
usageStringBuilder.Append(Environment.NewLine);
|
||||||
|
usageStringBuilder.Append($"- {usageItem.Usage.Replace("/", Environment.NewLine + "-")}");
|
||||||
|
|
||||||
writable = usageItem.Write;
|
writable = usageItem.Write;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usageString.Length == 0)
|
if (usageStringBuilder.Length == 0)
|
||||||
{
|
{
|
||||||
usageString = "Unknown.";
|
usageStringBuilder.Append("Unknown.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_gameUsageLabel.Text = $"Usage{(writable ? " (Writable)" : "")} : {usageString}";
|
_gameUsageLabel.Text = $"Usage{(writable ? " (Writable)" : "")} : {usageStringBuilder}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ namespace Ryujinx.Ui.Windows
|
||||||
|
|
||||||
if (str.Length > MaxSize)
|
if (str.Length > MaxSize)
|
||||||
{
|
{
|
||||||
return str.Substring(0, MaxSize - ShrinkChars.Length) + ShrinkChars;
|
return $"{str.AsSpan(0, MaxSize - ShrinkChars.Length)}{ShrinkChars}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
|
|
Reference in a new issue