public static void WriteAllConstants(CsCodeWriter cw, TypeNameMappings tnm, ConstantDefinition[] constants) { using (cw.PushBlock("public static partial class VulkanNative")) { foreach (ConstantDefinition constant in constants) { if (constant.Comment != null) { cw.WriteLine($"///<summary>{constant.Comment}</summary>"); } cw.WriteLine($"public const {GetCSharpNameForConstantType(constant.Type)} {EnumHelpers.GetPrettyEnumName(constant.Name, "VK_")} = {NormalizeValue(constant.Value)};"); } } cw.WriteLine(); using (cw.PushBlock("public static partial class RawConstants")) { foreach (ConstantDefinition constant in constants) { if (constant.Comment != null) { cw.WriteLine($"///<summary>{constant.Comment}</summary>"); } cw.WriteLine($"public const {GetCSharpNameForConstantType(constant.Type)} {constant.Name} = VulkanNative.{EnumHelpers.GetPrettyEnumName(constant.Name, "VK_")};"); } } }
public static void WriteEnum(CsCodeWriter cw, EnumDefinition enumDef, TypeNameMappings tnm) { if (enumDef.Name.EndsWith("FlagBits")) { } if (enumDef.Type == EnumType.Bitmask) { cw.WriteLine("[Flags]"); } string mappedName = tnm.GetMappedName(enumDef.Name); using (cw.PushBlock("public enum " + mappedName)) { string enumNamePrefix = GetEnumNamePrefix(mappedName); if (enumDef.Type == EnumType.Bitmask && !enumDef.Values.Any(ev => GetPrettyEnumName(ev.Name, enumNamePrefix) == "None")) { cw.WriteLine($"None = 0,"); } foreach (var value in enumDef.Values) { if (!string.IsNullOrEmpty(value.Comment)) { cw.WriteLine($"///<summary>{value.Comment}</summary>"); } string prettyName = GetPrettyEnumName(value.Name, enumNamePrefix); cw.WriteLine($"{prettyName} = {value.ValueOrBitPosition},"); } } }
public static void WriteHandle(CsCodeWriter cw, HandleDefinition handle) { if (handle.Parent != null) { cw.WriteIndentation(); cw.Write($"///<summary>"); cw.Write($"A {(handle.Dispatchable ? "dispatchable" : "non-dispatchable")} handle owned by a {handle.Parent}."); cw.Write("</summary>"); cw.Write(Environment.NewLine); } cw.WriteLine($"[DebuggerDisplay(\"{{DebuggerDisplay,nq}}\")]"); using (cw.PushBlock($"public partial struct {handle.Name} : IEquatable<{handle.Name}>")) { string handleType = handle.Dispatchable ? "IntPtr" : "ulong"; string nullValue = handle.Dispatchable ? "IntPtr.Zero" : "0"; cw.WriteLine($"public readonly {handleType} Handle;"); cw.WriteLine($"public {handle.Name}({handleType} existingHandle) {{ Handle = existingHandle; }}"); cw.WriteLine($"public static {handle.Name} Null => new {handle.Name}({nullValue});"); cw.WriteLine($"public static implicit operator {handle.Name}({handleType} handle) => new {handle.Name}(handle);"); cw.WriteLine($"public static bool operator ==({handle.Name} left, {handle.Name} right) => left.Handle == right.Handle;"); cw.WriteLine($"public static bool operator !=({handle.Name} left, {handle.Name} right) => left.Handle != right.Handle;"); cw.WriteLine($"public static bool operator ==({handle.Name} left, {handleType} right) => left.Handle == right;"); cw.WriteLine($"public static bool operator !=({handle.Name} left, {handleType} right) => left.Handle != right;"); cw.WriteLine($"public bool Equals({handle.Name} h) => Handle == h.Handle;"); cw.WriteLine($"public override bool Equals(object o) => o is {handle.Name} h && Equals(h);"); cw.WriteLine($"public override int GetHashCode() => Handle.GetHashCode();"); cw.WriteLine($"private string DebuggerDisplay => string.Format(\"{handle.Name} [0x{{0}}]\", Handle.ToString(\"X\"));"); } }
public static void WriteConstant(CsCodeWriter cw, TypeNameMappings tnm, ConstantDefinition constant) { if (constant.Comment != null) { cw.WriteLine($"///<summary>{constant.Comment}</summary>"); } cw.WriteLine($"public const {GetCSharpNameForConstantType(constant.Type)} {EnumHelpers.GetPrettyEnumName(constant.Name, "VK_")} = {NormalizeValue(constant.Value)};"); }
private static void WriteMember(CsCodeWriter cw, TypeNameMappings tnm, MemberSpec member, string nameSuffix) { if (!string.IsNullOrEmpty(member.Comment)) { cw.WriteLine($"///<summary>{member.Comment}</summary>"); } cw.WriteLine($"public {member.Type.MapTypeSpec(tnm)} {Util.NormalizeFieldName(member.Name)}{nameSuffix};"); }
private static void SpaceSeparatedList <T>(CsCodeWriter cw, IList <T> list, Action <T> action) { for (int i = 0; i < list.Count; i++) { var item = list[i]; action(item); if (i != list.Count - 1) { cw.WriteLine(); } } }
public static void WriteStructure(CsCodeWriter cw, StructureDefinition structure, TypeNameMappings tnm, ConstantDefinition[] constants) { using (cw.PushBlock("public unsafe partial struct " + structure.Name)) { foreach (var member in structure.Members) { if (member.ElementCount > 1) { for (int i = 0; i < member.ElementCount; i++) { WriteMember(cw, tnm, member, "_" + i); } } else if (member.ElementCountSymbolic != null) { var validConstant = constants.FirstOrDefault(cd => cd.Name == member.ElementCountSymbolic); if (validConstant != null) { WriteMemberSymbolicCount(cw, tnm, member, constants); } else { WriteMember(cw, tnm, member, string.Empty); } } else { WriteMember(cw, tnm, member, string.Empty); } } if (HasAnyFieldWithSpecifiedValues(structure)) { // Add a helper property which fills in the structure type. using (cw.PushBlock($"public static {structure.Name} New()")) { cw.WriteLine($"{structure.Name} ret = new {structure.Name}();"); foreach (var member in structure.Members.Where(ms => ms.LegalValues != null)) { cw.WriteLine($"ret.{member.Name} = {member.Type}.{GetDefaultValueString(member.Type, member.LegalValues)};"); } cw.WriteLine("return ret;"); } } } }
public static void WriteCommand(CsCodeWriter cw, TypeNameMappings tnm, CommandDefinition command) { if (!command.IsVariant) { cw.WriteLine($"private static IntPtr {command.Name}_ptr;"); } if (command.SuccessCodes.Length != 0) { cw.WriteLine($"///<remarks>Success codes:{string.Join(", ", command.SuccessCodes)}. Error codes:{string.Join(", ", command.ErrorCodes)}</remarks>"); } cw.WriteLine("[Generator.CalliRewrite]"); using (cw.PushBlock($"public static unsafe {command.ReturnType.MapTypeSpec(tnm)} {command.Name}({command.GetParametersSignature(tnm)})")) { cw.WriteLine("throw new NotImplementedException();"); } }
public static void WriteHandle(CsCodeWriter cw, HandleDefinition handle) { if (handle.Parent != null) { cw.WriteIndentation(); cw.Write($"///<summary>"); cw.Write($"A {(handle.Dispatchable ? "dispatchable" : "non-dispatchable")} handle owned by a {handle.Parent}."); cw.Write("</summary>"); cw.Write(Environment.NewLine); } using (cw.PushBlock("public partial struct " + handle.Name)) { cw.WriteLine("public readonly IntPtr Handle;"); cw.WriteLine($"public {handle.Name}(IntPtr existingHandle) {{ Handle = existingHandle; }}"); cw.WriteLine($"public static implicit operator {handle.Name}(IntPtr handle) => new {handle.Name}(handle);"); cw.WriteLine($"public static implicit operator IntPtr({handle.Name} handle) => handle.Handle;"); //cw.WriteLine($"public static bool operator ==({handle.Name} left, IntPtr right) => left.Handle == right;"); //cw.WriteLine($"public static bool operator !=({handle.Name} left, IntPtr right) => left.Handle != right;"); } }
private static void WriteMemberSymbolicCount(CsCodeWriter cw, TypeNameMappings tnm, MemberSpec member, ConstantDefinition[] constants) { if (!CanUseFixed(member.Type.MapTypeSpec(tnm))) { int count = GetSymbolValue(member.ElementCountSymbolic, constants); for (int i = 0; i < count; i++) { WriteMember(cw, tnm, member, "_" + i); } } else { if (!string.IsNullOrEmpty(member.Comment)) { cw.WriteLine($"///<summary>{member.Comment}</summary>"); } string mappedSymbolicName = EnumHelpers.GetPrettyEnumName(member.ElementCountSymbolic, "VK_"); cw.WriteLine($"public fixed {member.Type.MapTypeSpec(tnm)} {Util.NormalizeFieldName(member.Name)}[(int)VulkanNative.{mappedSymbolicName}];"); } }
public static void WriteCommand(CsCodeWriter cw, TypeNameMappings tnm, CommandDefinition command) { if (!command.IsVariant) { if (Configuration.GenerateCalliStubs) { cw.WriteLine($"private static IntPtr {command.Name}_ptr;"); } else { cw.WriteLine($"private delegate {command.ReturnType.MapTypeSpec(tnm)} {command.Name}_delegate({command.GetParametersSignature(tnm)});"); cw.WriteLine($"private static {command.Name}_delegate {command.Name}_ptr;"); } } if (command.SuccessCodes.Length != 0) { cw.WriteLine($"///<remarks>Success codes:{string.Join(", ", command.SuccessCodes)}. Error codes:{string.Join(", ", command.ErrorCodes)}</remarks>"); } if (Configuration.GenerateCalliStubs) { cw.WriteLine("[Generator.CalliRewrite]"); } using (cw.PushBlock($"public static unsafe {command.ReturnType.MapTypeSpec(tnm)} {command.Name}({command.GetParametersSignature(tnm)})")) { if (Configuration.GenerateCalliStubs) { cw.WriteLine("throw new NotImplementedException();"); } else { string invocation = string.Join(", ", command.Parameters.Select(pd => $"{pd.GetModifierString()}{Util.NormalizeFieldName(pd.Name)}")); string ret = (command.ReturnType.Name == "void") ? "" : "return "; cw.WriteLine($"{ret}{command.Name}_ptr({invocation});"); } } }
public static void WriteUnion(CsCodeWriter cw, TypeNameMappings tnm, StructureDefinition union) { cw.WriteLine("[StructLayout(LayoutKind.Explicit)]"); using (cw.PushBlock("public struct " + union.Name)) { foreach (var member in union.Members) { if (member.ElementCount > 1) { for (int i = 0; i < member.ElementCount; i++) { int fieldSize = Util.GetTypeSize(member.Type.MapTypeSpec(tnm)); cw.WriteLine($"[FieldOffset({i * fieldSize})]"); WriteMember(cw, tnm, member, "_" + i); } } else { cw.WriteLine("[FieldOffset(0)]"); WriteMember(cw, tnm, member, string.Empty); } } } }
public CodeBlock(CsCodeWriter cw, string header) { _cw = cw; _cw.WriteLine(header); _cw.PushBlock(); }
public static void WriteConstant(CsCodeWriter cw, TypeNameMappings tnm, ConstantDefinition constant) { }
public IfDefSection(CsCodeWriter cw, string condition) { _cw = cw; _condition = condition; _cw.WriteLine($"#if {condition}"); }
private static void GenerateAllTypes(VulkanSpecification spec, TypeNameMappings tnm, string path) { using (StreamWriter sw = File.CreateText(Path.Combine(path, "Structures.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(sw); cw.WriteHeader(); cw.WriteLine(); using (cw.PushIfDef(GetActiveCalliCondition())) { cw.Using("System"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) { SpaceSeparatedList(cw, spec.Structures, structure => { StructureHelpers.WriteStructure(cw, structure, tnm, spec.Constants); }); } } } using (StreamWriter enumWriter = File.CreateText(Path.Combine(path, "Enums.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(enumWriter); cw.WriteHeader(); cw.WriteLine(); using (cw.PushIfDef(GetActiveCalliCondition())) { cw.Using("System"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) { SpaceSeparatedList(cw, spec.Enums, enumDef => { EnumHelpers.WriteEnum(cw, enumDef, tnm); }); } } } CommandDefinition[] allVariants = spec.Commands.SelectMany(cd => VariantGenerator.GenerateVariants(cd)).ToArray(); CommandDefinition[] allCommandsWithVariants = spec.Commands.Concat(allVariants).OrderBy(cd => cd.Name).ToArray(); using (StreamWriter commandWriter = File.CreateText(Path.Combine(path, "Commands.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(commandWriter); cw.WriteHeader(); cw.WriteLine(); using (cw.PushIfDef(GetActiveCalliCondition())) { cw.Using("System"); cw.Using("System.Runtime.InteropServices"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) using (cw.PushBlock("public static unsafe partial class VulkanNative")) { SpaceSeparatedList(cw, spec.Constants, constant => { ConstantHelpers.WriteConstant(cw, tnm, constant); }); cw.WriteLine(); SpaceSeparatedList(cw, allCommandsWithVariants, command => { CommandHelpers.WriteCommand(cw, tnm, command); }); cw.WriteLine(); using (cw.PushBlock("private static void LoadFunctionPointers()")) { foreach (CommandDefinition command in spec.Commands) { if (Configuration.GenerateCalliStubs) { cw.WriteLine($"{command.Name}_ptr = s_nativeLib.LoadFunctionPointer(\"{command.Name}\");"); } else { cw.WriteLine($"IntPtr {command.Name}_nativePtr = s_nativeLib.LoadFunctionPointer(\"{command.Name}\");"); using (cw.PushBlock($"if ({command.Name}_nativePtr != IntPtr.Zero)")) { cw.WriteLine($"{command.Name}_ptr = Marshal.GetDelegateForFunctionPointer<{command.Name}_delegate>({command.Name}_nativePtr);"); } using (cw.PushBlock("else")) { string invocation = string.Join(", ", command.Parameters.Select(pd => Util.NormalizeFieldName(pd.Name))); cw.WriteLine($"{command.Name}_ptr = ({invocation}) => {{ throw CreateMissingFunctionException(); }};"); } } } } } } } using (StreamWriter handleWriter = File.CreateText(Path.Combine(path, "Handles.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(handleWriter); cw.WriteHeader(); cw.WriteLine(); using (cw.PushIfDef(GetActiveCalliCondition())) { cw.Using("System"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) { SpaceSeparatedList(cw, spec.Handles, handle => { HandleHelpers.WriteHandle(cw, handle); }); } } } using (StreamWriter unionWriter = File.CreateText(Path.Combine(path, "Unions.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(unionWriter); cw.WriteHeader(); cw.WriteLine(); using (cw.PushIfDef(GetActiveCalliCondition())) { cw.Using("System.Runtime.InteropServices"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) { SpaceSeparatedList(cw, spec.Unions, union => { UnionHelpers.WriteUnion(cw, tnm, union); }); } } } }
private static void GenerateAllTypes(VulkanSpecification spec, TypeNameMappings tnm, string path) { using (StreamWriter sw = File.CreateText(Path.Combine(path, "Structures.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(sw); cw.WriteHeader(); cw.WriteLine(); cw.Using("System"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) { Util.SpaceSeparatedList(cw, spec.Structures, structure => { StructureHelpers.WriteStructure(cw, structure, tnm, spec.Constants); }); } } using (StreamWriter enumWriter = File.CreateText(Path.Combine(path, "Enums.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(enumWriter); cw.WriteHeader(); cw.WriteLine(); cw.Using("System"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) { Util.SpaceSeparatedList(cw, spec.Enums, enumDef => { EnumHelpers.WriteEnum(cw, enumDef, tnm); }); } } CommandDefinition[] allVariants = spec.Commands.SelectMany(cd => VariantGenerator.GenerateVariants(cd)).ToArray(); CommandDefinition[] allCommandsWithVariants = spec.Commands.Concat(allVariants).OrderBy(cd => cd.Name).ToArray(); using (StreamWriter commandWriter = File.CreateText(Path.Combine(path, "Commands.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(commandWriter); cw.WriteHeader(); cw.WriteLine(); cw.Using("System"); cw.Using("System.Runtime.InteropServices"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) using (cw.PushBlock("public static unsafe partial class VulkanNative")) { Util.SpaceSeparatedList(cw, allCommandsWithVariants, command => { CommandHelpers.WriteCommand(cw, tnm, command); }); cw.WriteLine(); using (cw.PushBlock("private static void LoadFunctionPointers()")) { foreach (CommandDefinition command in spec.Commands) { cw.WriteLine($"{command.Name}_ptr = s_nativeLib.LoadFunctionPointer(\"{command.Name}\");"); } } } } using (StreamWriter handleWriter = File.CreateText(Path.Combine(path, "Handles.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(handleWriter); cw.WriteHeader(); cw.WriteLine(); cw.Using("System"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) { Util.SpaceSeparatedList(cw, spec.Handles, handle => { HandleHelpers.WriteHandle(cw, handle); }); } } using (StreamWriter unionWriter = File.CreateText(Path.Combine(path, "Unions.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(unionWriter); cw.WriteHeader(); cw.WriteLine(); cw.Using("System.Runtime.InteropServices"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) { Util.SpaceSeparatedList(cw, spec.Unions, union => { UnionHelpers.WriteUnion(cw, tnm, union); }); } } using (StreamWriter unionWriter = File.CreateText(Path.Combine(path, "Constants.gen.cs"))) { CsCodeWriter cw = new CsCodeWriter(unionWriter); cw.WriteHeader(); cw.WriteLine(); cw.Using("System.Runtime.InteropServices"); cw.WriteLine(); using (cw.PushBlock("namespace Vulkan")) { ConstantHelpers.WriteAllConstants(cw, tnm, spec.Constants); } } }