feat(meshopt): add typed enums and improve naming logic
Introduce SimplifyOptions and SimplifyVertexOptions enums for mesh simplification, replacing magic numbers with type-safe flags. Update MeshOptApi with strongly-typed wrapper methods. Refactor MeshletUtility to use new enums and nullable delegates, and fix stride calculation for pointer arithmetic. Rename NamingConventions.GetMethodName to GetName, update name removal logic to use "$TBare", and add ALL_CAPS style for constants. Update config files to match new naming conventions and add ALL_CAPS constant rule for meshopt. Refactor BindingParser and related classes to support constant member kind. Apply minor bug fixes and code style improvements throughout.
This commit is contained in:
@@ -276,7 +276,7 @@ public sealed class WrapperGeneratorEmitter
|
||||
{
|
||||
var func = routed.Function;
|
||||
var nameOpts = routed.Apply.Opts?.name;
|
||||
var methodName = naming.GetMethodName(func.Name, nameOpts, routed.TargetStructName);
|
||||
var methodName = naming.GetName(func.Name, nameOpts, routed.TargetStructName);
|
||||
|
||||
// Build the parameter plan: for each native parameter, determine the public type
|
||||
// and how to pass it to the Api call (applying remaps).
|
||||
|
||||
@@ -18,7 +18,6 @@ public sealed class NativeStruct
|
||||
public required bool IsList { get; init; }
|
||||
public required bool IsPointerList { get; init; }
|
||||
public string? ListElementType { get; init; }
|
||||
public required bool IsElementLike { get; init; }
|
||||
}
|
||||
|
||||
public sealed class NativeEnum
|
||||
@@ -52,4 +51,5 @@ public enum NativeMemberKind
|
||||
{
|
||||
Field,
|
||||
Property,
|
||||
Constant,
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ public sealed class BindingParser
|
||||
{
|
||||
public NativeLibrary Parse(string inputDirectory, WrapperConfig config)
|
||||
{
|
||||
var members = new List<NativeMember>();
|
||||
var structs = new List<NativeStruct>();
|
||||
var enums = new List<NativeEnum>();
|
||||
var functions = new List<NativeFunction>();
|
||||
@@ -33,18 +34,17 @@ public sealed class BindingParser
|
||||
continue;
|
||||
}
|
||||
|
||||
var members = ParseMembers(@struct);
|
||||
var listInfo = TryMatchList(members);
|
||||
var structMembers = ParseMembers(@struct);
|
||||
var listInfo = TryMatchList(structMembers);
|
||||
|
||||
structs.Add(new NativeStruct
|
||||
{
|
||||
Name = @struct.Identifier.ValueText,
|
||||
Namespace = namespaceName,
|
||||
Members = members,
|
||||
Members = structMembers,
|
||||
IsList = listInfo.IsList,
|
||||
IsPointerList = listInfo.IsPointerList,
|
||||
ListElementType = listInfo.ListElementType,
|
||||
IsElementLike = members.Any(static m => m.Name == "element" && m.TypeName == "ufbx_element"),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@ public sealed class NamingConventions
|
||||
///
|
||||
/// Supported remove tokens:
|
||||
/// "PREFIX" — strip the config's NativeTypePrefix from the start (e.g. "nvtt", "ufbx_")
|
||||
/// "NO_PREFIX($TSelf)" — strip the target struct name minus its type prefix from the start,
|
||||
/// "$TBare" — strip the target struct name minus its type prefix from the start,
|
||||
/// case-insensitively (e.g. NvttSurface → "Surface" stripped from "SurfaceWidth")
|
||||
///
|
||||
/// nameOpts is the dynamic opts.name object from JSON (may be null).
|
||||
/// If no nameOpts are provided, the name is returned with only the library prefix stripped.
|
||||
/// </summary>
|
||||
public string GetMethodName(string nativeFunctionName, dynamic? nameOpts, string targetStructName)
|
||||
public string GetName(string nativeFunctionName, dynamic? nameOpts, string targetStructName)
|
||||
{
|
||||
var name = nativeFunctionName;
|
||||
|
||||
@@ -47,13 +47,8 @@ public sealed class NamingConventions
|
||||
{
|
||||
name = StripPrefixIgnoreCase(name, _config.NativeTypePrefix);
|
||||
}
|
||||
else if (token.StartsWith("NO_PREFIX(", StringComparison.Ordinal) && token.EndsWith(')'))
|
||||
else if (string.Equals(token, "$TBare", StringComparison.Ordinal))
|
||||
{
|
||||
// Extract $TSelf — it's the literal token "NO_PREFIX($TSelf)", so the struct name
|
||||
// is resolved from the targetStructName argument passed in.
|
||||
// Strip the config prefix from the struct name to get the "bare" part.
|
||||
// Try prefix first, then suffix (handles both nvtt "SurfaceWidth"→"Width"
|
||||
// and ufbx "free_scene"→"free_" styles).
|
||||
var bareStructName = StripPrefixIgnoreCase(targetStructName, _config.NativeTypePrefix);
|
||||
|
||||
// Remove directly, the name maybe nvttSetOutputOptionsOutputHeader, if we only remove prefix and suffix, OutputOptions in the middle will be ignored, so we remove the bare struct name directly, case-insensitively.
|
||||
@@ -66,7 +61,7 @@ public sealed class NamingConventions
|
||||
var style = nameOpts.style as string;
|
||||
if (!string.IsNullOrEmpty(style))
|
||||
{
|
||||
if (string.Equals(style, "PascalCase", StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(style, "PascalCase", StringComparison.Ordinal))
|
||||
{
|
||||
int counter = 0;
|
||||
Span<char> nameSpan = stackalloc char[name.Length];
|
||||
@@ -83,10 +78,10 @@ public sealed class NamingConventions
|
||||
|
||||
if (name[i] == '_')
|
||||
{
|
||||
while (name[i] == '_' && i < name.Length)
|
||||
do
|
||||
{
|
||||
i++;
|
||||
}
|
||||
} while (i < name.Length && name[i] == '_');
|
||||
|
||||
nameSpan[counter] = char.ToUpperInvariant(name[i]);
|
||||
counter++;
|
||||
@@ -98,6 +93,54 @@ public sealed class NamingConventions
|
||||
counter++;
|
||||
}
|
||||
|
||||
name = nameSpan[..counter].ToString();
|
||||
}
|
||||
else if (string.Equals(style, "ALL_CAPS", StringComparison.Ordinal))
|
||||
{
|
||||
int counter = 0;
|
||||
Span<char> nameSpan = stackalloc char[name.Length * 2]; // Worst case, every character is uppercase and followed by an underscore.
|
||||
|
||||
for (int i = 0; i < name.Length; i++)
|
||||
{
|
||||
// ___ to _
|
||||
if (name[i] == '_')
|
||||
{
|
||||
while (i + 1 < name.Length && name[i + 1] == '_')
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
nameSpan[counter] = '_';
|
||||
counter++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// AbC to AB_C
|
||||
if (i > 0 && char.IsUpper(name[i]) && char.IsLower(name[i - 1]))
|
||||
{
|
||||
nameSpan[counter] = '_';
|
||||
counter++;
|
||||
}
|
||||
|
||||
// ABC to ABC
|
||||
while (i < name.Length && char.IsUpper(name[i]))
|
||||
{
|
||||
nameSpan[counter] = name[i];
|
||||
|
||||
counter++;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == name.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
nameSpan[counter] = char.ToUpperInvariant(name[i]);
|
||||
counter++;
|
||||
}
|
||||
|
||||
name = nameSpan[..counter].ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"name": {
|
||||
"remove": [
|
||||
"PREFIX",
|
||||
"NO_PREFIX($TSelf)" // NO_PREFIX(NvttSurface) will change "NvttSurface" to "Surface", the prefix is determined by the "nativeTypePrefix" field at the top level of this config
|
||||
"$TBare" // NO_PREFIX(NvttSurface) will change "NvttSurface" to "Surface", the prefix is determined by the "nativeTypePrefix" field at the top level of this config
|
||||
],
|
||||
"style": "PascalCase"
|
||||
}
|
||||
@@ -43,7 +43,7 @@
|
||||
"name": {
|
||||
"remove": [
|
||||
"PREFIX",
|
||||
"NO_PREFIX($TSelf)"
|
||||
"$TBare"
|
||||
],
|
||||
"style": "PascalCase"
|
||||
}
|
||||
@@ -64,6 +64,21 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"filter": "CONST",
|
||||
"targetType": "MeshOptApi",
|
||||
"apply": {
|
||||
"type": "CONST",
|
||||
"opts": {
|
||||
"name": {
|
||||
"remove": [
|
||||
"PREFIX"
|
||||
],
|
||||
"style": "ALL_CAPS"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"name": {
|
||||
"remove": [
|
||||
"PREFIX",
|
||||
"NO_PREFIX($TSelf)" // NO_PREFIX(NvttSurface) will change "NvttSurface" to "Surface", the prefix is determined by the "nativeTypePrefix" field at the top level of this config
|
||||
"$TBare" // NO_PREFIX(NvttSurface) will change "NvttSurface" to "Surface", the prefix is determined by the "nativeTypePrefix" field at the top level of this config
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -86,21 +86,7 @@
|
||||
"name": {
|
||||
"remove": [
|
||||
"PREFIX",
|
||||
"NO_PREFIX($TSelf)"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"filter": "EXTERN_API",
|
||||
"targetType": "NvttApi",
|
||||
"apply": {
|
||||
"type": "STATIC_METHOD",
|
||||
"opts": {
|
||||
"name": {
|
||||
"remove": [
|
||||
"PREFIX"
|
||||
"$TBare"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"name": {
|
||||
"remove": [
|
||||
"PREFIX",
|
||||
"NO_PREFIX($TSelf)" // NO_PREFIX(ufbx_scene) will output "scene" change "free_scene" to "free", the prefix is determined by the "nativeTypePrefix" field at the top level of this config
|
||||
"$TBare" // NO_PREFIX(ufbx_scene) will output "scene" change "free_scene" to "free", the prefix is determined by the "nativeTypePrefix" field at the top level of this config
|
||||
],
|
||||
"style": "PascalCase"
|
||||
}
|
||||
@@ -87,7 +87,7 @@
|
||||
"name": {
|
||||
"remove": [
|
||||
"PREFIX",
|
||||
"NO_PREFIX($TSelf)"
|
||||
"$TBare"
|
||||
],
|
||||
"style": "PascalCase"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user