Skip to content

Commit bd83421

Browse files
committed
Support nint, nuint, and NFloat
1 parent f0bdada commit bd83421

14 files changed

Lines changed: 844 additions & 132 deletions

File tree

AssetRipper.TextureDecoder.ColorGenerator/NumericConversionGenerator.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,11 @@ private static void WriteChangeSignMethods(IndentedTextWriter writer)
4242
{
4343
foreach ((CSharpPrimitives.Data unsignedType, CSharpPrimitives.Data signedType) in GetIntegerTypes())
4444
{
45-
WriteMethod(writer, unsignedType, signedType, unsignedType);
46-
WriteMethod(writer, signedType, unsignedType, unsignedType);
45+
if (!unsignedType.HasPointerSize(out _, out _))
46+
{
47+
WriteMethod(writer, unsignedType, signedType, unsignedType);
48+
WriteMethod(writer, signedType, unsignedType, unsignedType);
49+
}
4750
}
4851

4952
static void WriteMethod(IndentedTextWriter writer, CSharpPrimitives.Data parameterType, CSharpPrimitives.Data returnType, CSharpPrimitives.Data unsignedType)
@@ -105,10 +108,21 @@ private static void WriteConvertMethod(IndentedTextWriter writer, CSharpPrimitiv
105108
writer.WriteLine($"private static TTo {methodName}<TTo>({from.LangName} value) where TTo : unmanaged");
106109
using (new CurlyBrackets(writer))
107110
{
108-
if (from.IsSignedInteger(out CSharpPrimitives.Data? unsignedFromData))
111+
if (from.HasPointerSize(out CSharpPrimitives.Data? bit32From, out CSharpPrimitives.Data? bit64From))
112+
{
113+
using (new If(writer, "IntPtr.Size == sizeof(int)"))
114+
{
115+
writer.WriteLine($"return {ConvertMethodName(bit32From.Type)}<TTo>(({bit32From.LangName})value);");
116+
}
117+
using (new Else(writer))
118+
{
119+
writer.WriteLine($"return {ConvertMethodName(bit64From.Type)}<TTo>(({bit64From.LangName})value);");
120+
}
121+
}
122+
else if (from.IsSignedInteger(out CSharpPrimitives.Data? unsignedFrom))
109123
{
110-
writer.WriteLine($"{unsignedFromData.LangName} unsigned = {ChangeSign}(value);");
111-
writer.WriteLine($"return {ConvertMethodName(unsignedFromData.Type)}<TTo>(unsigned);");
124+
writer.WriteLine($"{unsignedFrom.LangName} unsigned = {ChangeSign}(value);");
125+
writer.WriteLine($"return {ConvertMethodName(unsignedFrom.Type)}<TTo>(unsigned);");
112126
}
113127
else
114128
{
@@ -122,6 +136,19 @@ private static void WriteConvertMethod(IndentedTextWriter writer, CSharpPrimitiv
122136
{
123137
writer.WriteLine($"return Unsafe.As<{to.LangName}, TTo>(ref value);");
124138
}
139+
else if (to.HasPointerSize(out CSharpPrimitives.Data? bit32To, out CSharpPrimitives.Data? bit64To))
140+
{
141+
using (new If(writer, "IntPtr.Size == sizeof(int)"))
142+
{
143+
writer.WriteLine($"{to.LangName} converted = ({to.LangName}){methodName}<{bit32To.LangName}>(value);");
144+
writer.WriteLine($"return Unsafe.As<{to.LangName}, TTo>(ref converted);");
145+
}
146+
using (new Else(writer))
147+
{
148+
writer.WriteLine($"{to.LangName} converted = ({to.LangName}){methodName}<{bit64To.LangName}>(value);");
149+
writer.WriteLine($"return Unsafe.As<{to.LangName}, TTo>(ref converted);");
150+
}
151+
}
125152
else if (to.IsSignedInteger(out CSharpPrimitives.Data? unsignedTo))
126153
{
127154
writer.WriteLine($"{to.LangName} converted = {ChangeSign}({methodName}<{unsignedTo.LangName}>(value));");

AssetRipper.TextureDecoder.ConsoleApp/Program.g.cs

Lines changed: 182 additions & 121 deletions
Large diffs are not rendered by default.

AssetRipper.TextureDecoder.SourceGeneration.Common/CSharpPrimitives.cs

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Diagnostics.CodeAnalysis;
22
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
34

45
namespace AssetRipper.TextureDecoder.SourceGeneration.Common;
56

@@ -13,12 +14,15 @@ public static class CSharpPrimitives
1314
{ typeof(ushort), new Data<ushort>() },
1415
{ typeof(int), new Data<int>() },
1516
{ typeof(uint), new Data<uint>() },
17+
{ typeof(nint), new Data<nint>() },
18+
{ typeof(nuint), new Data<nuint>() },
1619
{ typeof(long), new Data<long>() },
1720
{ typeof(ulong), new Data<ulong>() },
1821
{ typeof(Int128), new Data<Int128>() },
1922
{ typeof(UInt128), new Data<UInt128>() },
2023
{ typeof(Half), new Data<Half>() },
2124
{ typeof(float), new Data<float>() },
25+
{ typeof(NFloat), new Data<NFloat>() },
2226
{ typeof(double), new Data<double>() },
2327
{ typeof(decimal), new Data<decimal>() },
2428
};
@@ -31,14 +35,42 @@ public static class CSharpPrimitives
3135

3236
public static Data FirstData => List[0];
3337

38+
public static bool HasPointerSize(Type type, [NotNullWhen(true)] out Type? bit32Type, [NotNullWhen(true)] out Type? bit64Type)
39+
{
40+
if (type == typeof(nint))
41+
{
42+
bit32Type = typeof(int);
43+
bit64Type = typeof(long);
44+
return true;
45+
}
46+
else if (type == typeof(nuint))
47+
{
48+
bit32Type = typeof(uint);
49+
bit64Type = typeof(ulong);
50+
return true;
51+
}
52+
else if (type == typeof(NFloat))
53+
{
54+
bit32Type = typeof(float);
55+
bit64Type = typeof(double);
56+
return true;
57+
}
58+
else
59+
{
60+
bit32Type = null;
61+
bit64Type = null;
62+
return false;
63+
}
64+
}
65+
3466
public static bool IsFloatingPoint(Type type)
3567
{
36-
return type == typeof(Half) || type == typeof(float) || type == typeof(double) || type == typeof(decimal);
68+
return type == typeof(Half) || type == typeof(float) || type == typeof(NFloat) || type == typeof(double) || type == typeof(decimal);
3769
}
3870

3971
public static bool IsUnsignedInteger(Type type)
4072
{
41-
return type == typeof(byte) || type == typeof(ushort) || type == typeof(uint) || type == typeof(ulong) || type == typeof(UInt128);
73+
return type == typeof(byte) || type == typeof(ushort) || type == typeof(uint) || type == typeof(nuint) || type == typeof(ulong) || type == typeof(UInt128);
4274
}
4375

4476
public static bool IsSignedInteger(Type type, [NotNullWhen(true)] out Type? unsignedType)
@@ -55,6 +87,10 @@ public static bool IsSignedInteger(Type type, [NotNullWhen(true)] out Type? unsi
5587
{
5688
unsignedType = typeof(uint);
5789
}
90+
else if (type == typeof(nint))
91+
{
92+
unsignedType = typeof(nuint);
93+
}
5894
else if (type == typeof(long))
5995
{
6096
unsignedType = typeof(ulong);
@@ -113,6 +149,14 @@ public static string GetLangName(Type type)
113149
{
114150
return "uint";
115151
}
152+
else if (type == typeof(nint))
153+
{
154+
return "nint";
155+
}
156+
else if (type == typeof(nuint))
157+
{
158+
return "nuint";
159+
}
116160
else if (type == typeof(long))
117161
{
118162
return "long";
@@ -157,6 +201,21 @@ public abstract class Data
157201
public string TypeName => Type.Name;
158202
public string LangName => GetLangName(Type);
159203
public bool CanBeConstant => CanBeConstant(Type);
204+
public bool HasPointerSize([NotNullWhen(true)] out Data? bit32Data, [NotNullWhen(true)] out Data? bit64Data)
205+
{
206+
if (CSharpPrimitives.HasPointerSize(Type, out Type? bit32Type, out Type? bit64Type))
207+
{
208+
bit32Data = Dictionary[bit32Type];
209+
bit64Data = Dictionary[bit64Type];
210+
return true;
211+
}
212+
else
213+
{
214+
bit32Data = null;
215+
bit64Data = null;
216+
return false;
217+
}
218+
}
160219
public bool IsFloatingPoint => IsFloatingPoint(Type);
161220
public bool IsUnsignedInteger => IsUnsignedInteger(Type);
162221
public bool IsSignedInteger([NotNullWhen(true)] out Data? unsignedData)
@@ -182,6 +241,19 @@ private sealed class Data<T> : Data
182241
{
183242
public override Type Type => typeof(T);
184243

185-
public override int Size => Unsafe.SizeOf<T>();
244+
public override int Size
245+
{
246+
get
247+
{
248+
if (CSharpPrimitives.HasPointerSize(Type, out _, out _))
249+
{
250+
return 6;//arbitrary value between 4 and 8
251+
}
252+
else
253+
{
254+
return Unsafe.SizeOf<T>();
255+
}
256+
}
257+
}
186258
}
187-
}
259+
}

AssetRipper.TextureDecoder.TestGenerator/Program.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using AssetRipper.TextureDecoder.Rgb.Formats;
44
using AssetRipper.TextureDecoder.SourceGeneration.Common;
55
using System.CodeDom.Compiler;
6+
using System.Runtime.InteropServices;
67

78
namespace AssetRipper.TextureDecoder.TestGenerator
89
{
@@ -35,6 +36,7 @@ private static void GenerateRgbConsoleMethod()
3536
writer.WriteLine();
3637
writer.WriteLine($"using {typeof(RgbConverter).Namespace};");
3738
writer.WriteLine($"using {typeof(ColorBGRA32).Namespace};");
39+
writer.WriteLine($"using {typeof(NFloat).Namespace};");
3840
writer.WriteLine();
3941

4042
writer.WriteFileScopedNamespace("AssetRipper.TextureDecoder.ConsoleApp");
@@ -79,10 +81,9 @@ private static void GenerateRgbConsoleMethod()
7981
{
8082
foreach (CSharpPrimitives.Data primitiveData in CSharpPrimitives.List)
8183
{
82-
int primitiveBitSize = primitiveData.Size * 8;
8384
foreach (string genericColorName in TestClassGenerator.GetGenericColorNames())
8485
{
85-
string prettyName = $"{genericColorName}{primitiveBitSize}{primitiveData.TypeName}";
86+
string prettyName = $"{genericColorName}_{primitiveData.TypeName}";
8687
yield return (prettyName, $"{genericColorName}<{primitiveData.LangName}>", primitiveData.LangName);
8788
}
8889
}

AssetRipper.TextureDecoder.Tests/Formats/ColorARGB16Tests.g.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@ public void ConversionIsLosslessToColorRGBA_uint()
194194
LosslessConversion.Assert<ColorARGB16, byte, ColorRGBA<uint>, uint>();
195195
}
196196

197+
[Test]
198+
public void ConversionIsLosslessToColorRGBA_nint()
199+
{
200+
LosslessConversion.Assert<ColorARGB16, byte, ColorRGBA<nint>, nint>();
201+
}
202+
203+
[Test]
204+
public void ConversionIsLosslessToColorRGBA_nuint()
205+
{
206+
LosslessConversion.Assert<ColorARGB16, byte, ColorRGBA<nuint>, nuint>();
207+
}
208+
197209
[Test]
198210
public void ConversionIsLosslessToColorRGBA_long()
199211
{

AssetRipper.TextureDecoder.Tests/Formats/ColorARGB32Tests.g.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@ public void ConversionIsLosslessToColorRGBA_uint()
194194
LosslessConversion.Assert<ColorARGB32, byte, ColorRGBA<uint>, uint>();
195195
}
196196

197+
[Test]
198+
public void ConversionIsLosslessToColorRGBA_nint()
199+
{
200+
LosslessConversion.Assert<ColorARGB32, byte, ColorRGBA<nint>, nint>();
201+
}
202+
203+
[Test]
204+
public void ConversionIsLosslessToColorRGBA_nuint()
205+
{
206+
LosslessConversion.Assert<ColorARGB32, byte, ColorRGBA<nuint>, nuint>();
207+
}
208+
197209
[Test]
198210
public void ConversionIsLosslessToColorRGBA_long()
199211
{

AssetRipper.TextureDecoder.Tests/Formats/ColorBGRA32Tests.g.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@ public void ConversionIsLosslessToColorRGBA_uint()
194194
LosslessConversion.Assert<ColorBGRA32, byte, ColorRGBA<uint>, uint>();
195195
}
196196

197+
[Test]
198+
public void ConversionIsLosslessToColorRGBA_nint()
199+
{
200+
LosslessConversion.Assert<ColorBGRA32, byte, ColorRGBA<nint>, nint>();
201+
}
202+
203+
[Test]
204+
public void ConversionIsLosslessToColorRGBA_nuint()
205+
{
206+
LosslessConversion.Assert<ColorBGRA32, byte, ColorRGBA<nuint>, nuint>();
207+
}
208+
197209
[Test]
198210
public void ConversionIsLosslessToColorRGBA_long()
199211
{

AssetRipper.TextureDecoder.Tests/Formats/ColorRGB16Tests.g.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,30 @@ public void ConversionIsLosslessToColorRGB_uint()
230230
LosslessConversion.Assert<ColorRGB16, byte, ColorRGB<uint>, uint>();
231231
}
232232

233+
[Test]
234+
public void ConversionIsLosslessToColorRGBA_nint()
235+
{
236+
LosslessConversion.Assert<ColorRGB16, byte, ColorRGBA<nint>, nint>();
237+
}
238+
239+
[Test]
240+
public void ConversionIsLosslessToColorRGB_nint()
241+
{
242+
LosslessConversion.Assert<ColorRGB16, byte, ColorRGB<nint>, nint>();
243+
}
244+
245+
[Test]
246+
public void ConversionIsLosslessToColorRGBA_nuint()
247+
{
248+
LosslessConversion.Assert<ColorRGB16, byte, ColorRGBA<nuint>, nuint>();
249+
}
250+
251+
[Test]
252+
public void ConversionIsLosslessToColorRGB_nuint()
253+
{
254+
LosslessConversion.Assert<ColorRGB16, byte, ColorRGB<nuint>, nuint>();
255+
}
256+
233257
[Test]
234258
public void ConversionIsLosslessToColorRGBA_long()
235259
{

AssetRipper.TextureDecoder.Tests/Formats/ColorRGBA16Tests.g.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@ public void ConversionIsLosslessToColorRGBA_uint()
194194
LosslessConversion.Assert<ColorRGBA16, byte, ColorRGBA<uint>, uint>();
195195
}
196196

197+
[Test]
198+
public void ConversionIsLosslessToColorRGBA_nint()
199+
{
200+
LosslessConversion.Assert<ColorRGBA16, byte, ColorRGBA<nint>, nint>();
201+
}
202+
203+
[Test]
204+
public void ConversionIsLosslessToColorRGBA_nuint()
205+
{
206+
LosslessConversion.Assert<ColorRGBA16, byte, ColorRGBA<nuint>, nuint>();
207+
}
208+
197209
[Test]
198210
public void ConversionIsLosslessToColorRGBA_long()
199211
{

AssetRipper.TextureDecoder.Tests/Formats/Generic/GenericColorTests.g.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ namespace AssetRipper.TextureDecoder.Tests.Formats.Generic;
3333
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGB<uint>), typeof(uint) })]
3434
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGBA<uint>), typeof(uint) })]
3535
[TestFixture(TypeArgs = new Type[] { typeof(ColorA<uint>), typeof(uint) })]
36+
[TestFixture(TypeArgs = new Type[] { typeof(ColorR<nint>), typeof(nint) })]
37+
[TestFixture(TypeArgs = new Type[] { typeof(ColorRG<nint>), typeof(nint) })]
38+
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGB<nint>), typeof(nint) })]
39+
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGBA<nint>), typeof(nint) })]
40+
[TestFixture(TypeArgs = new Type[] { typeof(ColorA<nint>), typeof(nint) })]
41+
[TestFixture(TypeArgs = new Type[] { typeof(ColorR<nuint>), typeof(nuint) })]
42+
[TestFixture(TypeArgs = new Type[] { typeof(ColorRG<nuint>), typeof(nuint) })]
43+
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGB<nuint>), typeof(nuint) })]
44+
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGBA<nuint>), typeof(nuint) })]
45+
[TestFixture(TypeArgs = new Type[] { typeof(ColorA<nuint>), typeof(nuint) })]
3646
[TestFixture(TypeArgs = new Type[] { typeof(ColorR<long>), typeof(long) })]
3747
[TestFixture(TypeArgs = new Type[] { typeof(ColorRG<long>), typeof(long) })]
3848
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGB<long>), typeof(long) })]
@@ -63,6 +73,11 @@ namespace AssetRipper.TextureDecoder.Tests.Formats.Generic;
6373
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGB<float>), typeof(float) })]
6474
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGBA<float>), typeof(float) })]
6575
[TestFixture(TypeArgs = new Type[] { typeof(ColorA<float>), typeof(float) })]
76+
[TestFixture(TypeArgs = new Type[] { typeof(ColorR<NFloat>), typeof(NFloat) })]
77+
[TestFixture(TypeArgs = new Type[] { typeof(ColorRG<NFloat>), typeof(NFloat) })]
78+
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGB<NFloat>), typeof(NFloat) })]
79+
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGBA<NFloat>), typeof(NFloat) })]
80+
[TestFixture(TypeArgs = new Type[] { typeof(ColorA<NFloat>), typeof(NFloat) })]
6681
[TestFixture(TypeArgs = new Type[] { typeof(ColorR<double>), typeof(double) })]
6782
[TestFixture(TypeArgs = new Type[] { typeof(ColorRG<double>), typeof(double) })]
6883
[TestFixture(TypeArgs = new Type[] { typeof(ColorRGB<double>), typeof(double) })]

0 commit comments

Comments
 (0)