private void GenerateEnum(IndentedTextWriter writer, GLEnum glEnum, GLFeature feature, HashSet <GLChangeReference> collected) { bool any = false; using (var sb = new StringBuilderTextWriter(new StringBuilder())) using (var tempWriter = new IndentedTextWriter(sb)) { tempWriter.Indent = writer.Indent; tempWriter.WriteLine("enum " + glEnum.Name + " : uint"); tempWriter.WriteLine("{"); using (tempWriter.Indentation()) { foreach (var entry in glEnum.Entries) { var reference = new GLChangeReference("enum", entry.Value.Name); if (!collected.Contains(reference)) { continue; } any = true; tempWriter.WriteLine(entry.Value.Name + " = " + entry.Value.Value + ","); } } tempWriter.WriteLine("}"); if (any) { writer.WriteLine(sb.StringBuilder.ToString()); } } }
public void LoadPart(IGLSpecification spec, XElement root) { var features = spec.Features; foreach (var f in root.Elements("feature")) { var feature = new GLFeature(f.Attribute("api")?.Value, Version.Parse(f.Attribute("number")?.Value), f.Attribute("name")?.Value); foreach (var require in f.Elements("require")) { string profileName = require.Attribute("profile")?.Value; var profile = feature.GetOrCreateProfile(profileName); LoadStuff(profile.Additions, require); } foreach (var removal in f.Elements("remove")) { string profileName = removal.Attribute("profile")?.Value; var profile = feature.GetOrCreateProfile(profileName); LoadStuff(profile.Removals, removal); } features.Add(feature); } features.Sort(((a, b) => { var apiCompare = string.Compare(a.Api, b.Api, StringComparison.Ordinal); return(apiCompare == 0 ? a.Number.CompareTo(b.Number) : apiCompare); })); var previousFeature = features[0]; for (var i = 1; i < features.Count; i++) { var feature = features[i]; if (previousFeature.Api == feature.Api) { feature.InitializePreviousFeature(previousFeature); } previousFeature = feature; } }
private void GenerateMethod(IndentedTextWriter writer, GLMethod glMethod, GLFeature feature, HashSet <GLChangeReference> collected) { var reference = new GLChangeReference("command", glMethod.Name); if (!collected.Contains(reference)) { return; } writer.WriteLine($"[DllImport(\"OpenTK.OpenGL\", EntryPoint = \"{glMethod.Name}\")]"); writer.Write("public extern static "); writer.Write(glMethod.ReturnTypeBase + " " + glMethod.Name); writer.Write("("); bool isFirst = true; foreach (var p in glMethod.Parameters) { if (!isFirst) { writer.Write(", "); } var pType = p.Type; if (pType.IsConst) { writer.Write("[Const]"); pType = ((GLConstType)pType).ElementType; } writer.Write(pType.Name + " " + NameMangler.MangleParameter(p.Name)); isFirst = false; } writer.Write(");"); writer.WriteLine(); }
public void Generate(IGLSpecification spec, GLFeature feature) { using (var fs = new FileStream(Path.Combine(feature.Name, "OpenGL.csproj"), FileMode.Create)) using (var str = new StreamWriter(fs)) { str.WriteLine("<Project Sdk=\"Microsoft.NET.Sdk\">"); str.WriteLine(" <PropertyGroup>"); str.WriteLine(" <TargetFrameworks>netstandard2.0</TargetFrameworks>"); str.WriteLine(" <AllowUnsafeBlocks>true</AllowUnsafeBlocks>"); str.WriteLine(" </PropertyGroup>"); str.WriteLine("</Project>"); } foreach (var(profileName, profile) in feature.Profiles) { const string ext = ".cs"; const string prefix = "GL."; var profileFileAddition = string.IsNullOrEmpty(profileName) ? string.Empty : ("." + profileName); _namespaceGenerator.Generate(prefix + "Enums" + profileFileAddition + ext, _enumGenerator, spec, feature, profile, profileName); _namespaceGenerator.Generate(prefix + "Methods" + profileFileAddition + ext, _methodGenerator, spec, feature, profile, string.Empty); } }
private void GenerateSpecialNumbers(IndentedTextWriter writer, GLEnum glEnum, GLFeature feature, HashSet <GLChangeReference> collected) { bool any = false; using (var sb = new StringBuilderTextWriter(new StringBuilder())) using (var tempWriter = new IndentedTextWriter(sb)) { tempWriter.Indent = writer.Indent; tempWriter.WriteLine("public static class " + glEnum.Name + ""); tempWriter.WriteLine("{"); using (tempWriter.Indentation()) { foreach (var entry in glEnum.Entries) { var reference = new GLChangeReference("enum", entry.Value.Name); if (!collected.Contains(reference)) { continue; } any = true; string dataType = entry.Value.Value <= byte.MaxValue ? "byte" : entry.Value.Value <= ushort.MaxValue ? "ushort" : entry.Value.Value <= uint.MaxValue ? "uint" : "ulong"; tempWriter.WriteLine($"public static {dataType} {entry.Value.Name} = {entry.Value.Value};"); } } tempWriter.WriteLine("}"); if (any) { writer.WriteLine(sb.StringBuilder.ToString()); } } }
public void Generate(IndentedTextWriter indentedTextWriter, IGLSpecification spec, GLFeature feature, GLFeature.GLProfile profile) { var collected = feature.CollectFeatures(profile.Name); foreach (var e in spec.Enums.Values) { if (e.Name == "SpecialNumbers") { GenerateSpecialNumbers(indentedTextWriter, e, feature, collected); } else { GenerateEnum(indentedTextWriter, e, feature, collected); } } }
public void Generate(string outputFileName, IGenerator generator, IGLSpecification spec, GLFeature feature, GLFeature.GLProfile profile, string namesapceName) { string outputDir = feature.Name; if (!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } using (var fs = new FileStream(Path.Combine(outputDir, outputFileName), FileMode.Create)) using (var streamWriter = new StreamWriter(fs)) using (var indentedTextWriter = new IndentedTextWriter(streamWriter)) { indentedTextWriter.WriteLine("using System;"); indentedTextWriter.WriteLine("using System.Runtime.InteropServices;"); indentedTextWriter.WriteLine("namespace OpenTK.Graphics" + (string.IsNullOrWhiteSpace(namesapceName) ? string.Empty : "." + namesapceName)); indentedTextWriter.WriteLine("{"); using (indentedTextWriter.Indentation()) { generator.Generate(indentedTextWriter, spec, feature, profile); } indentedTextWriter.WriteLine("}"); } }
public void Generate(IndentedTextWriter indentedTextWriter, IGLSpecification spec, GLFeature feature, GLFeature.GLProfile profile) { var collected = feature.CollectFeatures(profile.Name); List <(GLMethod m, string name)> delegates = new List <(GLMethod m, string name)>(); foreach (var t in spec.Types.Values.OfType <GLTypeDef>()) { var resolved = t.OriginalType.Resolved(); if (resolved.IsMethod) { var methodType = (GLMethod)resolved; if (string.IsNullOrEmpty(profile.Name)) // Only add delegates in base profile { delegates.Add((methodType, t.Name)); } continue; } while (resolved.IsTypeDef) { resolved = ((GLTypeDef)resolved).OriginalType.Resolved(); } indentedTextWriter.WriteLine("using " + t.Name + " = " + resolved + ";"); } indentedTextWriter.WriteLine("public static unsafe partial class GL"); indentedTextWriter.WriteLine("{"); using (indentedTextWriter.Indentation()) { foreach (var(del, delName) in delegates) { indentedTextWriter.Write("public delegate " + del.ReturnTypeBase + " " + delName + "("); bool first = true; foreach (var p in del.Parameters) { if (!first) { indentedTextWriter.Write(", "); } var pType = p.Type; if (pType.IsConst) { indentedTextWriter.Write("[Const]"); pType = ((GLConstType)pType).ElementType; } indentedTextWriter.Write(pType + " " + p.Name); first = false; } indentedTextWriter.WriteLine(");"); } if (!string.IsNullOrEmpty(profile.Name)) { indentedTextWriter.WriteLine("public static class " + profile.Name); indentedTextWriter.WriteLine("{"); indentedTextWriter.Indent++; } foreach (var e in spec.Methods.Values) { GenerateMethod(indentedTextWriter, e, feature, collected); } if (!string.IsNullOrEmpty(profile.Name)) { indentedTextWriter.Indent--; indentedTextWriter.WriteLine("}"); } } indentedTextWriter.WriteLine("}"); }