generate glenum, link glenum, add source gen for text regex
This commit is contained in:
@@ -42,59 +42,76 @@ namespace StgSharp.GenerateGL.Generation
|
||||
StringComparer.Ordinal);
|
||||
|
||||
public static GeneratedFileSet Generate(
|
||||
GlRegistryProjection projection
|
||||
GlRegistryProjection projection,
|
||||
GlGenerationTarget target = GlGenerationTarget.All
|
||||
)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(projection);
|
||||
if (target == GlGenerationTarget.None || (target & ~GlGenerationTarget.All) != 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(target));
|
||||
}
|
||||
|
||||
IReadOnlyList<GlCommandGroup> commandGroups = ReadCoreCommandGroups(projection);
|
||||
IReadOnlyList<GlCommandDefinition> commands = Array.AsReadOnly(
|
||||
commandGroups.SelectMany(value => value.Commands).ToArray());
|
||||
GlEquivalentTypeMapper typeMapper = new GlEquivalentTypeMapper(projection.Source);
|
||||
GlFunctionFamilyAnalysis familyAnalysis = GlFunctionFamilyAnalyzer.Analyze(projection);
|
||||
ManagedApiPlanner apiPlanner = new ManagedApiPlanner(typeMapper, familyAnalysis);
|
||||
IReadOnlyList<ManagedMethodDefinition> managedMethods = apiPlanner.Plan(commands);
|
||||
Dictionary<string, IReadOnlyList<ManagedMethodDefinition>> methodsByCommand =
|
||||
managedMethods.GroupBy(value => value.NativeCommand.Name, StringComparer.Ordinal)
|
||||
.ToDictionary(
|
||||
value => value.Key,
|
||||
value => (IReadOnlyList<ManagedMethodDefinition>)Array.AsReadOnly(
|
||||
value.ToArray()),
|
||||
StringComparer.Ordinal);
|
||||
List<ManagedCommandGroup> managedGroups = commandGroups.Select(
|
||||
group => new ManagedCommandGroup(
|
||||
group,
|
||||
Array.AsReadOnly(
|
||||
group.Commands.SelectMany(
|
||||
command => methodsByCommand.TryGetValue(
|
||||
command.Name,
|
||||
out IReadOnlyList<ManagedMethodDefinition>? methods)
|
||||
? methods
|
||||
: Array.Empty<ManagedMethodDefinition>())
|
||||
.ToArray()))).ToList();
|
||||
ManagedApiPlanner.Validate(
|
||||
managedGroups.SelectMany(value => value.Methods));
|
||||
List<GeneratedFile> files = new List<GeneratedFile>
|
||||
IReadOnlyList<ManagedEnumDefinition> enums = GlEnumProjector.Project(projection);
|
||||
GlEnumTypeMap enumTypeMap = new GlEnumTypeMap(enums);
|
||||
List<GeneratedFile> files = new List<GeneratedFile>();
|
||||
if ((target & GlGenerationTarget.Enum) != 0)
|
||||
{
|
||||
new GeneratedFile("glconst.cs", GenerateConstants(projection.Enums)),
|
||||
new GeneratedFile(
|
||||
files.Add(new GeneratedFile("glconst.cs", GenerateConstants(projection.Enums)));
|
||||
files.Add(new GeneratedFile("GlEnums.g.cs", GenerateEnums(enums)));
|
||||
}
|
||||
|
||||
if ((target & GlGenerationTarget.Api) != 0)
|
||||
{
|
||||
IReadOnlyList<GlCommandGroup> commandGroups = ReadCoreCommandGroups(projection);
|
||||
IReadOnlyList<GlCommandDefinition> commands = Array.AsReadOnly(
|
||||
commandGroups.SelectMany(value => value.Commands).ToArray());
|
||||
GlEquivalentTypeMapper typeMapper = new GlEquivalentTypeMapper(projection.Source);
|
||||
GlFunctionFamilyAnalysis familyAnalysis = GlFunctionFamilyAnalyzer.Analyze(projection);
|
||||
ManagedApiPlanner apiPlanner = new ManagedApiPlanner(
|
||||
typeMapper,
|
||||
familyAnalysis,
|
||||
enumTypeMap);
|
||||
IReadOnlyList<ManagedMethodDefinition> managedMethods = apiPlanner.Plan(commands);
|
||||
Dictionary<string, IReadOnlyList<ManagedMethodDefinition>> methodsByCommand =
|
||||
managedMethods.GroupBy(value => value.NativeCommand.Name, StringComparer.Ordinal)
|
||||
.ToDictionary(
|
||||
value => value.Key,
|
||||
value => (IReadOnlyList<ManagedMethodDefinition>)Array.AsReadOnly(
|
||||
value.ToArray()),
|
||||
StringComparer.Ordinal);
|
||||
List<ManagedCommandGroup> managedGroups = commandGroups.Select(
|
||||
group => new ManagedCommandGroup(
|
||||
group,
|
||||
Array.AsReadOnly(
|
||||
group.Commands.SelectMany(
|
||||
command => methodsByCommand.TryGetValue(
|
||||
command.Name,
|
||||
out IReadOnlyList<ManagedMethodDefinition>? methods)
|
||||
? methods
|
||||
: Array.Empty<ManagedMethodDefinition>())
|
||||
.ToArray()))).ToList();
|
||||
ManagedApiPlanner.Validate(
|
||||
managedGroups.SelectMany(value => value.Methods));
|
||||
files.Add(new GeneratedFile(
|
||||
"OpenglContext.g.cs",
|
||||
GenerateContext(commands, typeMapper)),
|
||||
new GeneratedFile(
|
||||
GenerateContext(commands, typeMapper)));
|
||||
files.Add(new GeneratedFile(
|
||||
"glContextShadow.g.cs",
|
||||
GenerateContextShadow(commands)),
|
||||
};
|
||||
for (int index = 0; index < managedGroups.Count; index++)
|
||||
{
|
||||
ManagedCommandGroup managedGroup = managedGroups[index];
|
||||
GlCommandGroup group = managedGroup.Source;
|
||||
files.Add(
|
||||
new GeneratedFile(
|
||||
group.FileName,
|
||||
GenerateFunctions(
|
||||
managedGroup.Methods,
|
||||
group.Description,
|
||||
index == 0)));
|
||||
GenerateContextShadow(commands)));
|
||||
for (int index = 0; index < managedGroups.Count; index++)
|
||||
{
|
||||
ManagedCommandGroup managedGroup = managedGroups[index];
|
||||
GlCommandGroup group = managedGroup.Source;
|
||||
files.Add(
|
||||
new GeneratedFile(
|
||||
group.FileName,
|
||||
GenerateFunctions(
|
||||
managedGroup.Methods,
|
||||
group.FileName,
|
||||
group.Description,
|
||||
index == 0)));
|
||||
}
|
||||
}
|
||||
|
||||
return new GeneratedFileSet(files);
|
||||
@@ -184,7 +201,7 @@ namespace StgSharp.GenerateGL.Generation
|
||||
)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(512 * 1024);
|
||||
AppendGeneratedHeader(builder, "Desktop OpenGL constants");
|
||||
AppendGeneratedHeader(builder, "glconst.cs", "Desktop OpenGL constants");
|
||||
builder.Append("namespace StgSharp.Graphics.OpenGL\n");
|
||||
builder.Append("{\n");
|
||||
builder.Append(" public static class glConst\n");
|
||||
@@ -227,6 +244,60 @@ namespace StgSharp.GenerateGL.Generation
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private static string GenerateEnums(
|
||||
IReadOnlyList<ManagedEnumDefinition> enums
|
||||
)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(512 * 1024);
|
||||
AppendGeneratedHeader(
|
||||
builder,
|
||||
"GlEnums.g.cs",
|
||||
"Strongly typed desktop OpenGL enum groups");
|
||||
builder.Append("namespace StgSharp.Graphics.OpenGL\n");
|
||||
builder.Append("{\n");
|
||||
foreach (ManagedEnumDefinition value in enums)
|
||||
{
|
||||
builder.Append(" /// <summary>Native OpenGL group");
|
||||
builder.Append(value.NativeGroups.Count == 1 ? " " : "s ");
|
||||
builder.Append(string.Join(", ", value.NativeGroups));
|
||||
builder.Append(".</summary>\n");
|
||||
if (value.IsFlags)
|
||||
{
|
||||
builder.Append(" [System.Flags]\n");
|
||||
}
|
||||
|
||||
builder.Append(" public enum ");
|
||||
builder.Append(value.Name);
|
||||
builder.Append(" : uint\n");
|
||||
builder.Append(" {\n");
|
||||
foreach (ManagedEnumMemberDefinition member in value.Members)
|
||||
{
|
||||
builder.Append(" ");
|
||||
builder.Append(member.Name);
|
||||
builder.Append(" = ");
|
||||
if (member.NativeValue.Name == "GL_NONE" &&
|
||||
member.NativeValue.Comment ==
|
||||
"Synthetic zero value for a generated flags enum.")
|
||||
{
|
||||
builder.Append("0u");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("unchecked((uint)glConst.");
|
||||
builder.Append(ReadConstantName(member.NativeValue.Name));
|
||||
builder.Append(')');
|
||||
}
|
||||
|
||||
builder.Append(",\n");
|
||||
}
|
||||
|
||||
builder.Append(" }\n\n");
|
||||
}
|
||||
|
||||
builder.Append("}\n");
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private static ConstantExpression ReadConstantExpression(
|
||||
GlEnumDefinition value
|
||||
)
|
||||
@@ -329,7 +400,10 @@ namespace StgSharp.GenerateGL.Generation
|
||||
)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(128 * 1024);
|
||||
AppendGeneratedHeader(builder, "Desktop OpenGL core function pointer table");
|
||||
AppendGeneratedHeader(
|
||||
builder,
|
||||
"OpenglContext.g.cs",
|
||||
"Desktop OpenGL core function pointer table");
|
||||
builder.Append("namespace StgSharp.Graphics.OpenGL\n");
|
||||
builder.Append("{\n");
|
||||
builder.Append(" [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]\n");
|
||||
@@ -360,7 +434,10 @@ namespace StgSharp.GenerateGL.Generation
|
||||
)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(64 * 1024);
|
||||
AppendGeneratedHeader(builder, "Native-address shadow of the OpenGL function pointer table");
|
||||
AppendGeneratedHeader(
|
||||
builder,
|
||||
"glContextShadow.g.cs",
|
||||
"Native-address shadow of the OpenGL function pointer table");
|
||||
builder.Append("namespace StgSharp.Graphics.OpenGL\n");
|
||||
builder.Append("{\n");
|
||||
builder.Append(" [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]\n");
|
||||
@@ -389,13 +466,14 @@ namespace StgSharp.GenerateGL.Generation
|
||||
|
||||
private static string GenerateFunctions(
|
||||
IReadOnlyList<ManagedMethodDefinition> methods,
|
||||
string outputFileName,
|
||||
string description,
|
||||
bool includeContextState
|
||||
)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(512 * 1024);
|
||||
AppendGeneratedHeader(builder, description);
|
||||
builder.Append("using StgSharp.Mathematics.Graphics;\n\n");
|
||||
AppendGeneratedHeader(builder, outputFileName, description);
|
||||
builder.Append("using StgSharp.Mathematics.Numeric.Graphics;\n\n");
|
||||
builder.Append("using System;\n");
|
||||
builder.Append("using System.Runtime.CompilerServices;\n\n");
|
||||
builder.Append("namespace StgSharp.Graphics.OpenGL\n");
|
||||
@@ -572,6 +650,12 @@ namespace StgSharp.GenerateGL.Generation
|
||||
{
|
||||
builder.Append("return GlHandle.Create(");
|
||||
}
|
||||
else if (method.IsEnumReturn)
|
||||
{
|
||||
builder.Append("return (");
|
||||
builder.Append(method.ReturnType);
|
||||
builder.Append(')');
|
||||
}
|
||||
else if (method.ReturnType != "void")
|
||||
{
|
||||
builder.Append("return ");
|
||||
@@ -719,7 +803,14 @@ namespace StgSharp.GenerateGL.Generation
|
||||
ManagedParameterDefinition parameter = method.Parameters[
|
||||
parameterArgument.ParameterIndex];
|
||||
string parameterName = EscapeIdentifier(parameter.Name);
|
||||
if (!parameter.IsHandle)
|
||||
if (parameter.IsEnum)
|
||||
{
|
||||
builder.Append("(uint");
|
||||
builder.Append('*', parameter.Type.Count(value => value == '*'));
|
||||
builder.Append(')');
|
||||
builder.Append(parameterName);
|
||||
}
|
||||
else if (!parameter.IsHandle)
|
||||
{
|
||||
builder.Append(parameterName);
|
||||
}
|
||||
@@ -769,9 +860,18 @@ namespace StgSharp.GenerateGL.Generation
|
||||
|
||||
private static void AppendGeneratedHeader(
|
||||
StringBuilder builder,
|
||||
string outputFileName,
|
||||
string description
|
||||
)
|
||||
{
|
||||
builder.Append("// -----------------------------------------------------------------------------\n");
|
||||
builder.Append("// file=\"");
|
||||
builder.Append(ReadGeneratedFileName(outputFileName));
|
||||
builder.Append("\"\n");
|
||||
builder.Append("// Project: StgSharp\n");
|
||||
builder.Append("// Copyright (c) Nitload.\n");
|
||||
builder.Append("// SPDX-License-Identifier: MIT\n");
|
||||
builder.Append("// -----------------------------------------------------------------------------\n\n");
|
||||
builder.Append("// <auto-generated>\n");
|
||||
builder.Append("// Generated by StgSharp.GenerateGL.\n");
|
||||
builder.Append("// ");
|
||||
@@ -780,6 +880,22 @@ namespace StgSharp.GenerateGL.Generation
|
||||
builder.Append("// </auto-generated>\n\n");
|
||||
}
|
||||
|
||||
private static string ReadGeneratedFileName(
|
||||
string outputFileName
|
||||
)
|
||||
{
|
||||
const string generatedExtension = ".g.cs";
|
||||
const string sourceExtension = ".cs";
|
||||
if (outputFileName.EndsWith(generatedExtension, StringComparison.Ordinal))
|
||||
{
|
||||
return outputFileName[..^generatedExtension.Length];
|
||||
}
|
||||
|
||||
return outputFileName.EndsWith(sourceExtension, StringComparison.Ordinal)
|
||||
? outputFileName[..^sourceExtension.Length]
|
||||
: outputFileName;
|
||||
}
|
||||
|
||||
private sealed record ConstantExpression(
|
||||
string Type,
|
||||
string Literal
|
||||
|
||||
Reference in New Issue
Block a user