/// <inheritdoc /> public IEnumerable <Enum> ReadEnums(object obj, ProfileConverterOptions opts) { var spec = (VulkanSpecification)obj; opts.TypeMaps.Insert(0, spec.BaseTypes); var enums = ConvertEnums(spec, opts); var tm = new Dictionary <string, string>(); foreach (var feature in spec.Features.Select(x => x.Api).RemoveDuplicates()) { foreach (var(_, e) in enums) { tm.Add(e.NativeName, e.Name.Replace("FlagBits", "Flags")); yield return(new Enum { Attributes = e.Attributes, ExtensionName = "Core", Name = e.Name.Replace("FlagBits", "Flags"), NativeName = e.NativeName.Replace("FlagBits", "Flags"), ProfileName = feature, ProfileVersion = null, Tokens = e.Tokens }); } } opts.TypeMaps.Insert(0, tm); }
/// <inheritdoc /> public IEnumerable <Constant> ReadConstants(object obj, ProfileConverterOptions opts) { var spec = (VulkanSpecification)obj; return(spec.Constants.Select ( x => new Constant { Name = Naming.Translate(TrimName(x.Name, opts), opts.Prefix), NativeName = x.Name, Value = x.Value, Type = x.Type switch { ConstantType.Float32 => new Type { Name = "float" }, ConstantType.UInt32 => new Type { Name = "uint" }, ConstantType.UInt64 => new Type { Name = "ulong" }, _ => new Type { Name = "ulong" } } }
public IEnumerable <Struct> ReadStructs(object obj, ProfileConverterOptions opts) { var xd = (XDocument)obj; var rawStructs = xd.Element("registry")?.Element("types")?.Elements("type") .Where(typex => typex.HasCategoryAttribute("struct")) .Select(typex => StructureDefinition.CreateFromXml(typex)) .ToArray(); var structs = ConvertStructs(rawStructs, opts); foreach (var feature in xd.Element("registry").Elements("feature").Attributes("api").Select(x => x.Value).RemoveDuplicates()) { foreach (var(_, s) in structs) { yield return(new Struct { Attributes = s.Attributes, ExtensionName = "Core", Fields = s.Fields, Functions = s.Functions, Name = s.Name, NativeName = s.NativeName, ProfileName = feature, ProfileVersion = null }); } } opts.TypeMaps.Add(structs.ToDictionary(x => x.Key, x => x.Value.Name)); }
public string TrimName(string name, ProfileConverterOptions opts) { if (name.StartsWith($"{opts.Prefix.ToUpper()}_")) { return(name.Remove(0, opts.Prefix.Length + 1)); } return(name.StartsWith(opts.Prefix) ? name.Remove(0, opts.Prefix.Length) : name); }
/// <inheritdoc /> public IEnumerable <Function> ReadFunctions(object obj, ProfileConverterOptions opts) { var spec = (VulkanSpecification)obj; var functions = ConvertFunctions(spec, opts); foreach (var feature in spec.Features) { foreach (var name in feature.CommandNames) { if (functions.ContainsKey(name)) { var function = functions[name]; yield return(new Function { ExtensionName = "Core", Categories = new List <string> { TrimName(feature.Name, opts) }, Name = function.Name, NativeName = function.NativeName, Parameters = function.Parameters, ReturnType = function.ReturnType, ProfileName = feature.Api, ProfileVersion = feature.Number }); } } } foreach (var extension in spec.Extensions) { foreach (var name in extension.CommandNames) { foreach (var api in extension.Supported) { if (functions.ContainsKey(name)) { var function = functions[name]; yield return(new Function { ExtensionName = TrimName(extension.Name, opts), Categories = new List <string> { TrimName(extension.Name, opts) }, Name = function.Name, NativeName = function.NativeName, Parameters = function.Parameters, ReturnType = function.ReturnType, ProfileName = api, ProfileVersion = null }); } } } } }
public void WriteStructs(Profile profile, IEnumerable <Struct> structs, ProfileConverterOptions opts) { var map = new Dictionary <string, string>(); foreach (var @struct in structs) { if (@struct.ProfileName != profile.Name || @struct.ProfileVersion?.ToString(2) != profile.Version) { continue; } var category = FormatCategory(@struct.ExtensionName); // check that the root project exists if (!profile.Projects.ContainsKey("Core")) { profile.Projects.Add ( "Core", new Project { CategoryName = "Core", ExtensionName = "Core", IsRoot = true, Namespace = string.Empty } ); } // check that the extension project exists, if applicable if (@struct.ExtensionName != "Core" && !profile.Projects.ContainsKey(category)) { profile.Projects.Add ( category, new Project { CategoryName = category, ExtensionName = $"{opts.Prefix.ToUpper()}_{category}", IsRoot = false, Namespace = $".{category.CheckMemberName(opts.Prefix)}" } ); } // add the struct profile.Projects[@struct.ExtensionName == "Core" ? "Core" : category].Structs.Add(@struct); // add the struct to the type map map[@struct.NativeName] = @struct.Name; } // register the type map profile.TypeMaps.Add(map); }
private IEnumerable <Field> GetFields(StructureDefinition union, ProfileConverterOptions opts) { foreach (var x in union.Members) { if (x.ElementCount > 1) { for (var i = 0; i < x.ElementCount; i++) { var fieldSize = GetTypeSize(x.Type.Name, opts.TypeMaps); yield return(new Field { Name = $"{Naming.Translate(x.Name, opts.Prefix)}_{i}", Attributes = new List <Attribute> { new Attribute { Name = "FieldOffset", Arguments = new List <string> { $"{i * fieldSize}" } } }, Doc = $"/// <summary>{x.Comment}</summary>", NativeName = x.Name, NativeType = x.Type.ToString(), Type = ConvertType(x.Type), }); } } else { yield return(new Field { Name = $"{Naming.Translate(x.Name, opts.Prefix)}", Attributes = new List <Attribute> { new Attribute { Name = "FieldOffset", Arguments = new List <string> { "0" } } }, Doc = $"/// <summary>{x.Comment}</summary>", NativeName = x.Name, NativeType = x.Type.ToString(), Type = ConvertType(x.Type) }); } } }
/// <summary> /// Writes a collection of enums to their appropriate projects. /// </summary> /// <param name="profile">The profile to write the projects to.</param> /// <param name="enums">The enums to write.</param> public void WriteEnums(Profile profile, IEnumerable <Enum> enums, ProfileConverterOptions opts) { if (!profile.Projects.ContainsKey("Core")) { profile.Projects.Add ( "Core", new Project { CategoryName = "Core", ExtensionName = "Core", IsRoot = false, Namespace = string.Empty } ); } profile.Projects["Core"].Enums.AddRange(enums); profile.TypeMaps.Add(enums.RemoveDuplicates((x, y) => x.NativeName == y.NativeName).ToDictionary(x => x.NativeName, x => x.Name)); }
/// <inheritdoc /> public IEnumerable <Struct> ReadStructs(object obj, ProfileConverterOptions opts) { var spec = (VulkanSpecification)obj; var structs = ConvertStructs(spec, opts); foreach (var feature in spec.Features.Select(x => x.Api).RemoveDuplicates()) { foreach (var(_, s) in structs) { yield return(new Struct { Attributes = s.Attributes, ExtensionName = "Core", Fields = s.Fields, Functions = s.Functions, Name = s.Name, NativeName = s.NativeName, ProfileName = feature, ProfileVersion = null }); } } }
//////////////////////////////////////////////////////////////////////////////////////// // Function Parsing //////////////////////////////////////////////////////////////////////////////////////// public IEnumerable <Function> ReadFunctions(object obj, ProfileConverterOptions opts) { var doc = obj as XDocument; var allFunctions = doc.Element("registry").Elements("commands") .Elements("command") .Select(x => TranslateCommand(x, opts)) .ToDictionary(x => x.Attribute("name")?.Value, x => x); var apis = doc.Element("registry").Elements("feature").Concat(doc.Element("registry").Elements("extensions").Elements("extension")); var removals = doc.Element("registry").Elements("feature") .Elements("remove") .Elements("command") .Attributes("name") .Select(x => x.Value) .ToList(); foreach (var api in apis) { foreach (var requirement in api.Elements("require")) { var apiName = requirement.Attribute("api")?.Value ?? api.Attribute("api")?.Value ?? api.Attribute("supported")?.Value ?? "gl"; var apiVersion = api.Attribute("number") != null ? Version.Parse(api.Attribute("number").Value) : null; foreach (var name in apiName.Split('|')) { foreach (var function in requirement.Elements("command") .Attributes("name") .Select(x => x.Value)) { var xf = allFunctions[TrimName(function, opts)]; var ret = new Function { Attributes = removals.Contains(function) ? new List <Attribute> { new Attribute { Name = "System.Obsolete", Arguments = new List <string> { $"\"Deprecated in version {apiVersion?.ToString(2)}\"" } } } : new List <Attribute>(), Categories = new List <string> { TrimName(api.Attribute("name")?.Value, opts) }, Doc = string.Empty, ExtensionName = api.Name == "feature" ? "Core" : TrimName(api.Attribute("name")?.Value, opts), GenericTypeParameters = new List <GenericTypeParameter>(), Name = Naming.Translate(NameTrimmer.Trim(TrimName(xf.Attribute("name")?.Value, opts), opts.Prefix), opts.Prefix), NativeName = function, Parameters = ParseParameters(xf), ProfileName = name, ProfileVersion = apiVersion, ReturnType = ParseTypeSignature(xf.Element("returns")) }; yield return(ret); if (api.Name == "feature" && name == "gl" && ret.Attributes.Count == 0) { yield return(new Function { Attributes = new List <Attribute>(), Categories = ret.Categories, Doc = ret.Doc, ExtensionName = ret.ExtensionName, GenericTypeParameters = new List <GenericTypeParameter>(), Name = ret.Name, NativeName = ret.NativeName, Parameters = ret.Parameters, ProfileName = "glcore", ProfileVersion = apiVersion, ReturnType = ret.ReturnType }); } allFunctions.Remove(function); } } } } }
public IEnumerable <Struct> ReadStructs(object obj, ProfileConverterOptions opts) { return(Enumerable.Empty <Struct>()); }
private Dictionary <string, Struct> ConvertStructs(StructureDefinition[] spec, ProfileConverterOptions opts) { var prefix = opts.Prefix; var ret = new Dictionary <string, Struct>(); foreach (var s in spec) { ret.Add ( s.Name, new Struct { Fields = s.Members.Select ( x => new Field { Count = string.IsNullOrEmpty(x.ElementCountSymbolic) ? x.ElementCount != 1 ? new Count(x.ElementCount) : null : new Count(x.ElementCountSymbolic, false), Name = Naming.Translate(TrimName(x.Name, opts), prefix), Doc = $"/// <summary>{x.Comment}</summary>", NativeName = x.Name, NativeType = x.Type.ToString(), Type = ConvertType(x.Type) } ) .ToList(), Name = Naming.TranslateLite(TrimName(s.Name, opts), prefix), NativeName = s.Name } ); } return(ret); }
private Dictionary <string, Struct> ConvertStructs(VulkanSpecification spec, ProfileConverterOptions opts) { var prefix = opts.Prefix; var ret = new Dictionary <string, Struct>(); foreach (var s in spec.Structures) { ret.Add ( s.Name, new Struct { Fields = s.Members.Select ( x => new Field { Count = string.IsNullOrEmpty(x.ElementCountSymbolic) ? x.ElementCount != 1 ? new Count(x.ElementCount) : null : new Count(x.ElementCountSymbolic, false), Name = Naming.Translate(TrimName(x.Name, opts), prefix), Doc = $"/// <summary>{x.Comment}</summary>", NativeName = x.Name, NativeType = x.Type.ToString(), Type = ConvertType(x.Type), DefaultAssignment = x.Type.Name == "VkStructureType" && !string.IsNullOrWhiteSpace(x.LegalValues) ? "StructureType." + TryTrim ( Naming.Translate ( TrimName(x.LegalValues.Split(',').FirstOrDefault(), opts), opts.Prefix ), Naming.TranslateLite(TrimName("VkStructureType", opts), opts.Prefix) ) : null } ) .ToList(), Name = Naming.TranslateLite(TrimName(s.Name, opts), prefix), NativeName = s.Name } ); } foreach (var h in spec.Handles) { ret.Add ( h.Name, new Struct { Fields = new List <Field> { new Field { Name = "Handle", Type = new Type { Name = h.CanBeDispatched ? "IntPtr" : "ulong" } } }, Name = Naming.TranslateLite(TrimName(h.Name, opts), prefix), NativeName = h.Name } ); } foreach (var u in spec.Unions) { ret.Add(u.Name, new Struct { Attributes = new List <Attribute> { new Attribute { Name = "StructLayout", Arguments = new List <string> { "LayoutKind.Explicit" } } }, Fields = GetFields(u, opts).ToList(), Name = Naming.TranslateLite(TrimName(u.Name, opts), prefix), NativeName = u.Name }); } return(ret); }
/// <inheritdoc /> public void WriteConstants(Profile profile, IEnumerable <Constant> constants, ProfileConverterOptions opts) { profile.Constants.AddRange(constants); }
private Dictionary <string, Function> ConvertFunctions(VulkanSpecification spec, ProfileConverterOptions opts) { var ret = new Dictionary <string, Function>(); foreach (var function in spec.Commands) { ret.Add ( function.Name, new Function { Name = Naming.Translate(NameTrimmer.Trim(TrimName(function.Name, opts), opts.Prefix), opts.Prefix), Parameters = function.Parameters.Select ( x => new Parameter { Count = x.IsNullTerminated ? null : x.ElementCountSymbolic != null ? new Count(x.ElementCountSymbolic.Split(',')) : new Count(x.ElementCount), Flow = ConvertFlow(x.Modifier), Name = x.Name, Type = ConvertType(x.Type) } ) .ToList(), NativeName = function.Name, ReturnType = ConvertType(function.ReturnType) } ); } return(ret); }
/// <inheritdoc /> public void WriteEnums(Profile profile, IEnumerable <Enum> enums, ProfileConverterOptions opts) { var mergedEnums = new Dictionary <string, Enum>(); var gl = profile.ClassName.ToUpper().CheckMemberName(opts.Prefix); mergedEnums.Add ( $"{gl}Enum", new Enum { Name = $"{gl}Enum", ExtensionName = "Core", Attributes = new List <Attribute>(), Tokens = new List <Token>(), NativeName = "GLenum", } ); if (!profile.Projects.ContainsKey("Core")) { profile.Projects.Add ( "Core", new Project { CategoryName = "Core", ExtensionName = "Core", IsRoot = true, Namespace = string.Empty } ); } // first, we need to categorise the enums into "Core", or their vendor (i.e. "NV", "SGI", "KHR" etc) foreach (var @enum in enums) { if (@enum.ProfileName != profile.Name || @enum.ProfileVersion?.ToString(2) != profile.Version) { continue; } switch (@enum.ExtensionName) { case "Core": mergedEnums[$"{gl}Enum"].Tokens.AddRange(@enum.Tokens); break; case "Core (Grouped)": @enum.ExtensionName = "Core"; profile.Projects["Core"].Enums.Add(@enum); break; default: { var prefix = FormatCategory(@enum.ExtensionName); if (!mergedEnums.ContainsKey(prefix)) { mergedEnums.Add ( prefix, new Enum { Name = prefix.CheckMemberName(opts.Prefix), ExtensionName = prefix, NativeName = "GLenum" } ); } mergedEnums[prefix].Tokens.AddRange(@enum.Tokens); break; } } } // now that we've categorised them, lets add them into their appropriate projects. foreach (var(_, @enum) in mergedEnums) { if (!profile.Projects.ContainsKey(@enum.ExtensionName)) { profile.Projects.Add ( @enum.ExtensionName, new Project { CategoryName = @enum.ExtensionName, ExtensionName = @enum.ExtensionName, IsRoot = @enum.ExtensionName == "Core", Namespace = @enum.ExtensionName == "Core" ? string.Empty : $".{@enum.ExtensionName.CheckMemberName(opts.Prefix)}" } ); } profile.Projects[@enum.ExtensionName].Enums.Add(@enum); } }
public void WriteConstants(Profile profile, IEnumerable <Constant> constants, ProfileConverterOptions opts) { // do nothing }
public void WriteConstants(Profile profile, IEnumerable <Constant> constants, ProfileConverterOptions opts) { profile.Constants.AddRange(constants.Where(x => profile.Constants.All(y => y.Name != x.Name))); }
/// <inheritdoc /> public void WriteStructs(Profile profile, IEnumerable <Struct> structs, ProfileConverterOptions opts) { profile.Projects["Core"].Structs.AddRange(structs); }
/// <summary> /// Writes a collection of functions to their appropriate projects. /// </summary> /// <param name="profile">The profile to write the projects to.</param> /// <param name="functions">The functions to write.</param> public void WriteFunctions(Profile profile, IEnumerable <Function> functions, ProfileConverterOptions opts) { foreach (var function in functions) { if (function.ProfileName != profile.Name || function.ProfileVersion?.ToString(2) != profile.Version) { continue; } foreach (var rawCategory in function.Categories) { var category = FormatCategory(rawCategory); var preCategory = $"{opts.Prefix.ToUpper()}_{rawCategory}"; // check that the root project exists if (!profile.Projects.ContainsKey("Core")) { profile.Projects.Add ( "Core", new Project { CategoryName = "Core", ExtensionName = "Core", IsRoot = true, Namespace = string.Empty } ); } // check that the extension project exists, if applicable if (function.ExtensionName != "Core" && !profile.Projects.ContainsKey(category)) { profile.Projects.Add ( category, new Project { CategoryName = category, ExtensionName = $"{opts.Prefix.ToUpper()}_{category}", IsRoot = false, Namespace = $".{category.CheckMemberName(opts.Prefix)}" } ); } // check that the interface exists if ( !profile.Projects[function.ExtensionName == "Core" ? "Core" : category] .Interfaces.ContainsKey(preCategory) ) { profile.Projects[function.ExtensionName == "Core" ? "Core" : category] .Interfaces.Add ( preCategory, new Interface { Name = $"I{Naming.Translate(TrimName(rawCategory, opts), opts.Prefix).CheckMemberName(opts.Prefix)}" } ); } // add the function to the interface profile.Projects[function.ExtensionName == "Core" ? "Core" : category] .Interfaces[preCategory] .Functions.Add(function); } } }
public void WriteStructs(Profile profile, IEnumerable <Struct> structs, ProfileConverterOptions opts) { // do nothing }