private void TranslateEnumGroups(XmlSpecData spec, DotNetApiData api, Options options) { foreach (var specEnumGroup in spec.EnumGroups.Where(x => options.EnumGroupFilter(x.Name))) { var enumGroupData = new DotNetEnumGroupData() { Name = specEnumGroup.Name, }; foreach (var enumName in specEnumGroup.Enums.Distinct()) { var xmlEnumData = spec.Enums.SingleOrDefault(x => x.Name == enumName); if (xmlEnumData == null || !options.EnumFilter(xmlEnumData)) continue; var enumData = api.Enums.SingleOrDefault(x => x.OriginalName == enumName); if (enumData == null) continue; enumGroupData.Enums.Add(enumData); if (spec.Enums.Single(x => x.Name == enumName).Type == "bitmask") enumGroupData.IsFlags = true; } api.EnumGroups.Add(enumGroupData); } }
private void WriteConstantsFile(DotNetApiData api, Options options) { string fileName = Path.Combine(options.OutputPath, options.ConstantsFileName); using (StreamWriter file = new StreamWriter(File.Open(fileName, FileMode.Create))) { file.WriteLine("using System;"); file.WriteLine(); file.WriteLine($"namespace {options.Namespace}"); file.WriteLine("{"); file.WriteLine($"\tpublic partial class {options.ConstantsClassName}"); file.WriteLine("\t{"); foreach (var @enum in api.Enums) { file.WriteLine("\t\t/// <summary>"); file.WriteLine("\t\t/// {0}", @enum.OriginalName); file.WriteLine("\t\t/// </summary>"); string name = @enum.OriginalName.Substring(options.Prefix.Length + 1); if (char.IsDigit(name[0])) name = "_" + name; file.WriteLine("\t\tpublic const {0} {1} = {2};", @enum.Type, name, @enum.Value); file.WriteLine(); } file.WriteLine("\t}"); file.WriteLine(); file.WriteLine("}"); } }
public void WriteFiles(DotNetApiData api, Options options) { this.WriteConstantsFile(api, options); this.WriteEnumFile(api, options); this.WriteNativeFunctionsFile(api, options); this.WriteDotNetFunctionsFile(api, options); }
private static IEnumerable<DotNetCommandData> GetSpecCommands(DotNetApiData api) { return api.Commands .Where(x => x.IsFromSpec) .OrderBy(x => x.VersionMajor) .ThenBy(x => x.VersionMinor) .ThenBy(x => x.NativeName); }
public void WriteFiles(DotNetApiData api, Options options) { this.WriteConstantsFile(api, options); this.WriteEnumFile(api, options); this.WriteCommandsFile(api, options); this.WriteContextFile(api, options); this.WriteOverloadsFile(api, options); }
public DotNetApiData Translate(XmlSpecData spec, Options options) { DotNetApiData api = new DotNetApiData(); this.TranslateEnums(spec, api, options); this.TranslateEnumGroups(spec, api, options); this.TranslateFunctions(spec, api, options); return api; }
private void TranslateEnums(XmlSpecData spec, DotNetApiData api, Options options) { foreach (var specEnum in spec.Enums.Where(x => options.EnumFilter(x))) { var enumData = new DotNetEnumData() { OriginalName = specEnum.Name, Name = this.InflectEnumName(specEnum.Name, options), Value = specEnum.Value, Type = specEnum.Value.Length <= 6 ? "uint" : "ulong" }; if (enumData.Value.StartsWith("-")) enumData.Value = string.Format("unchecked((uint){0})", enumData.Value); api.Enums.Add(enumData); } }
public void WriteNativeFunctionsFile(DotNetApiData api, Options options) { string fileName = Path.Combine(options.OutputPath, options.FunctionsFileName); using (StreamWriter file = new StreamWriter(File.Open(fileName, FileMode.Create))) { file.WriteLine("using System;"); file.WriteLine("using System.Runtime.InteropServices;"); file.WriteLine("using System.Text;"); file.WriteLine(); file.WriteLine("namespace {0}", options.Namespace); file.WriteLine("{"); file.WriteLine("\tinternal static partial class {0}", options.FunctionsClassName); file.WriteLine("\t{"); file.WriteLine("\t\tprivate const string Library = \"opengl32.dll\";"); file.WriteLine(); foreach (var function in api.Functions.Where(x => x.IsNative)) { if (function.CanPInvoke) { file.WriteLine(this.GetNativeDeclaration("\t\t", function, false)); } else { file.WriteLine(this.GetDelegateDeclaration("\t\t", function)); } file.WriteLine(); } file.WriteLine("\t}"); file.WriteLine("}"); } }
private void TranslateFunctions(XmlSpecData spec, DotNetApiData api, Options options) { foreach (var specCommand in spec.Commands.Where(x => options.CommandFilter(x))) { var specFeature = spec.Features.Where(x => x.Commands.Contains(specCommand.Name)).FirstOrDefault(); var functionData = new DotNetFunctionData() { IsNative = true, OriginalName = specCommand.Name, NativeName = this.InflectFunctionNativeName(specCommand.Name, options), DotNetName = this.InflectFunctionDotNetName(specCommand.Name, options), OriginalReturnType = specCommand.ReturnType, NativeReturnType = this.InflectNativeReturnType(specCommand), DotNetReturnType = this.InflectDotNetReturnType(specCommand) }; if (specFeature != null) { functionData.VersionMajor = specFeature.VersionMajor; functionData.VersionMinor = specFeature.VersionMinor; functionData.CanPInvoke = specFeature.VersionMajor == 1 && specFeature.VersionMinor <= 1; } if (functionData.NativeReturnType == "string") functionData.IsUnsafe = true; foreach (var specCommandParam in specCommand.Params) { var functionParamData = new DotNetFunctionParamData() { OriginalName = specCommandParam.Name, Name = this.InflectFunctionParamName(specCommandParam.Name), OriginalType = specCommandParam.Type, NativeType = this.InflectFunctionParamNativeType(specCommandParam), DotNetType = this.InflectFunctionParamDotNetType(specCommandParam), IsPointer = this.IsTypePointer(specCommandParam.Type), IsOutput = this.IsTypeOutput(specCommandParam.Type), ShouldUseGenerics = this.ShouldUseGenericsForType(specCommandParam.Type), ShouldUseFixed = this.ShouldUseFixedForParam(specCommandParam), ShouldUseAddressOfOperator = this.ShouldUseAddressOfOperatorForParam(specCommandParam) }; if (functionParamData.IsPointer) functionData.IsUnsafe = true; if (functionParamData.ShouldUseGenerics) functionData.ShouldUseGenerics = true; if (functionParamData.IsOutput && functionParamData.DotNetType == "IntPtr") { functionParamData.ShouldUseOut = true; } functionData.Params.Add(functionParamData); } api.Functions.Add(functionData); // Create overload which accepts the Enum variant. if (specCommand.Params.Any(x => this.IsTypeEnum(x, api))) { api.Functions.Add(this.ChangeFunctionParamsToEnums(functionData, specCommand.Params.Where(x => this.IsTypeEnum(x, api)))); } } foreach (var functionData in api.Functions.ToArray()) { var specCommand = spec.Commands.Single(x => x.Name == functionData.OriginalName); // Commands which take a pointer and it could be a single element. if (specCommand.Params.Any(x => this.ShouldChangeFunctionParamToRefOrOut(x))) { api.Functions.Add(this.ChangeFunctionParamsToRefOrOut(functionData, specCommand.Params.Where(x => this.ShouldChangeFunctionParamToRefOrOut(x)).Select(x => x.Name))); } // Commands which take a pointer and it could be a single element. if (specCommand.Params.Any(x => this.ShouldChangeFunctionParamToIntPtr(x))) { api.Functions.Add(this.ChangeFunctionParamsToIntPtr(functionData, specCommand.Params.Where(x => this.ShouldChangeFunctionParamToIntPtr(x)).Select(x => x.Name))); } } api.Functions.Sort((x, y) => x.OriginalName != null && y.OriginalName != null ? x.OriginalName.CompareTo(y.OriginalName) : 0); }
public bool IsTypeEnum(XmlCommandParamData param, DotNetApiData api) { return (param.Type == "GLenum" || param.Type == "GLbitfield") && !string.IsNullOrEmpty(param.TypeGroup) && api.EnumGroups.Any(x => x.Name == param.TypeGroup); }
private void WriteEnumFile(DotNetApiData api, Options options) { if (api.EnumGroups.Count == 0) return; string fileName = Path.Combine(options.OutputPath, options.EnumsFileName); using (StreamWriter file = new StreamWriter(File.Open(fileName, FileMode.Create))) { file.WriteLine("using System;"); file.WriteLine(); file.WriteLine("namespace {0}", options.Namespace); file.WriteLine("{"); foreach (var enumGroup in api.EnumGroups) { if (enumGroup.IsFlags) file.WriteLine("\t[Flags]"); file.WriteLine("\tpublic enum {0} : uint", enumGroup.Name); file.WriteLine("\t{"); foreach (var @enum in enumGroup.Enums) { file.WriteLine("\t\t/// <summary>"); file.WriteLine("\t\t/// {0}", @enum.OriginalName); file.WriteLine("\t\t/// </summary>"); file.WriteLine("\t\t{0} = {1},", @enum.Name, @enum.Value); file.WriteLine(); } file.WriteLine("\t}"); file.WriteLine(); } file.WriteLine("}"); } }
public void WriteDotNetFunctionsFile(DotNetApiData api, Options options) { string fileName = Path.Combine(options.OutputPath, options.ContextFileName); using (StreamWriter file = new StreamWriter(File.Open(fileName, FileMode.Create))) { file.WriteLine("using System;"); file.WriteLine("using System.Runtime.InteropServices;"); file.WriteLine("using System.Text;"); file.WriteLine(); file.WriteLine("namespace {0}", options.Namespace); file.WriteLine("{"); file.WriteLine("\tpublic partial class {0}", options.ContextClassName); file.WriteLine("\t{"); file.WriteLine("\t\tprivate void InitializeDelegates(int versionMajor, int versionMinor)"); file.WriteLine("\t\t{"); int versionMajor = -1; int versionMinor = -1; foreach (var function in api.Functions.Where(x => !x.CanPInvoke && x.IsNative).OrderBy(x => x.VersionMajor).ThenBy(x => x.VersionMinor).ThenBy(x => x.NativeName)) { if (versionMajor != function.VersionMajor || versionMinor != function.VersionMinor) { if (versionMajor != -1) { file.WriteLine("\t\t\t}"); file.WriteLine(); } versionMajor = function.VersionMajor; versionMinor = function.VersionMinor; file.WriteLine("\t\t\tif (versionMajor > {0} || (versionMajor == {0} && versionMinor >= {1}))", versionMajor, versionMinor); file.WriteLine("\t\t\t{"); } file.WriteLine("\t\t\t\tthis._" + function.NativeName + " = (" + options.FunctionsClassName + "." + function.NativeName + ")this.LoadExtensionFunction<" + options.FunctionsClassName + "." + function.NativeName + ">();"); } file.WriteLine("\t\t\t}"); file.WriteLine("\t\t}"); file.WriteLine(); foreach (var function in api.Functions) { if (!function.CanPInvoke && function.IsNative) { file.WriteLine("\t\tprivate " + options.FunctionsClassName + "." + function.NativeName + " _" + function.NativeName + ";"); file.WriteLine(); } file.WriteLine(this.GetDotNetDeclaration("\t\t", function, options)); file.WriteLine(); } file.WriteLine("\t}"); file.WriteLine("}"); } }
public void WriteOverloadsFile(DotNetApiData api, Options options) { string fileName = Path.Combine(options.OutputPath, "GLContext.Overloads.Generated.cs"); StringBuilder sb = new StringBuilder(1024); foreach (string template in Directory.EnumerateFiles(Path.Combine("Templates", "Overloads")).Select(x => Path.GetFileNameWithoutExtension(x))) { if (api.Commands.Any(x => x.DotNetName == template)) { sb.AppendLine(File.ReadAllText(Path.Combine("Templates", "Overloads", template + ".tmpl")).TrimEnd()); sb.AppendLine(); } } TemplateEngine.Run("GLContext.Overloads", fileName, new Dictionary<string, string> { { "Namespace", options.Namespace }, { "Overloads", sb.ToString().TrimEnd() } }); }
public void WriteContextFile(DotNetApiData api, Options options) { string fileName = Path.Combine(options.OutputPath, options.ContextFileName); using (StreamWriter file = new StreamWriter(File.Open(fileName, FileMode.Create))) { file.WriteLine("using System;"); file.WriteLine("using System.Runtime.InteropServices;"); file.WriteLine("using System.Text;"); file.WriteLine(); file.WriteLine("namespace {0}", options.Namespace); file.WriteLine("{"); file.WriteLine("\tpublic partial class {0}", options.ContextClassName); file.WriteLine("\t{"); var specCommands = GetSpecCommands(api); foreach (var command in specCommands) { file.WriteLine("\t\tprivate " + options.CommandsClassName + "." + command.NativeName + " _" + command.NativeName + ";"); file.WriteLine(); } if (options.ContextInitializeDelegatesByVersionNumber) file.WriteLine("\t\tprivate void InitializeCommands(int versionMajor, int versionMinor)"); else file.WriteLine("\t\tprivate void InitializeCommands()"); file.WriteLine("\t\t{"); int versionMajor = -1; int versionMinor = -1; if (options.ContextInitializeDelegatesByVersionNumber) { foreach (var function in specCommands) { if (versionMajor != function.VersionMajor || versionMinor != function.VersionMinor) { if (versionMajor != -1) { file.WriteLine("\t\t\t}"); file.WriteLine(); } versionMajor = function.VersionMajor; versionMinor = function.VersionMinor; file.WriteLine("\t\t\tif (versionMajor > {0} || (versionMajor == {0} && versionMinor >= {1}))", versionMajor, versionMinor); file.WriteLine("\t\t\t{"); } file.WriteLine("\t\t\t\tthis._" + function.NativeName + " = (" + options.CommandsClassName + "." + function.NativeName + ")this.LoadCommand<" + options.CommandsClassName + "." + function.NativeName + ">();"); } file.WriteLine("\t\t\t}"); } else { foreach (var function in specCommands) { file.WriteLine("\t\t\tthis._" + function.NativeName + " = (" + options.CommandsClassName + "." + function.NativeName + ")this.LoadCommand<" + options.CommandsClassName + "." + function.NativeName + ">();"); } } file.WriteLine("\t\t}"); file.WriteLine(); foreach (var function in api.Commands) { file.WriteLine(this.GetDotNetDeclaration("\t\t", function, options)); file.WriteLine(); } file.WriteLine("\t}"); file.WriteLine("}"); } }
public void WriteCommandsFile(DotNetApiData api, Options options) { string fileName = Path.Combine(options.OutputPath, options.CommandsFileName); using (StreamWriter file = new StreamWriter(File.Open(fileName, FileMode.Create))) { file.WriteLine("using System;"); file.WriteLine("using System.Runtime.InteropServices;"); file.WriteLine("using System.Text;"); file.WriteLine(); file.WriteLine("#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member"); file.WriteLine(); file.WriteLine("namespace {0}", options.Namespace); file.WriteLine("{"); file.WriteLine("\tpublic static partial class {0}", options.CommandsClassName); file.WriteLine("\t{"); foreach (var function in GetSpecCommands(api)) { file.WriteLine(this.GetDelegateDeclaration("\t\t", function)); file.WriteLine(); } file.WriteLine("\t}"); file.WriteLine("}"); } }