Mercurial > games > semicongine
comparison src/vulkan_api/vulkan_api_generator.nim @ 80:637da715b604
add: fix name clashes
| author | Sam <sam@basx.dev> |
|---|---|
| date | Wed, 22 Feb 2023 18:22:20 +0700 |
| parents | 031f241de6ca |
| children | fa1b6107deae |
comparison
equal
deleted
inserted
replaced
| 79:031f241de6ca | 80:637da715b604 |
|---|---|
| 77 func tableSorted(table: Table[int, string]): seq[(int, string)] = | 77 func tableSorted(table: Table[int, string]): seq[(int, string)] = |
| 78 result = toSeq(table.pairs) | 78 result = toSeq(table.pairs) |
| 79 result.sort((a, b) => cmp(a[0], b[0])) | 79 result.sort((a, b) => cmp(a[0], b[0])) |
| 80 | 80 |
| 81 # serializers | 81 # serializers |
| 82 func serializeEnum(node: XmlNode, root: XmlNode): seq[string] = | 82 func serializeEnum(node: XmlNode, api: XmlNode): seq[string] = |
| 83 let name = node.attr("name") | 83 let name = node.attr("name") |
| 84 if name == "": | 84 if name == "": |
| 85 return result | 85 return result |
| 86 | 86 |
| 87 var reservedNames: seq[string] | |
| 88 for t in api.findAll("type"): | |
| 89 reservedNames.add t.attr("name").replace("_", "").toLower() | |
| 90 | |
| 87 # find additional enum defintion in feature definitions | 91 # find additional enum defintion in feature definitions |
| 88 var values: Table[int, string] | 92 var values: Table[int, string] |
| 89 for feature in root.findAll("feature"): | 93 for feature in api.findAll("feature"): |
| 90 for require in feature.findAll("require"): | 94 for require in feature.findAll("require"): |
| 91 for theenum in require.findAll("enum"): | 95 for theenum in require.findAll("enum"): |
| 92 if theenum.attr("extends") == name: | 96 if theenum.attr("extends") == name: |
| 93 if theenum.hasAttr("offset"): | 97 if theenum.hasAttr("offset"): |
| 94 let enumBase = 1000000000 + (smartParseInt(theenum.attr("extnumber")) - 1) * 1000 | 98 let enumBase = 1000000000 + (smartParseInt(theenum.attr("extnumber")) - 1) * 1000 |
| 109 elif theenum.hasAttr("alias"): | 113 elif theenum.hasAttr("alias"): |
| 110 discard | 114 discard |
| 111 else: | 115 else: |
| 112 raise newException(Exception, &"Unknown extension value: {feature}\nvalue:{theenum}") | 116 raise newException(Exception, &"Unknown extension value: {feature}\nvalue:{theenum}") |
| 113 # find additional enum defintion in extension definitions | 117 # find additional enum defintion in extension definitions |
| 114 for extension in root.findAll("extension"): | 118 for extension in api.findAll("extension"): |
| 115 let extensionNumber = parseInt(extension.attr("number")) | 119 let extensionNumber = parseInt(extension.attr("number")) |
| 116 let enumBase = 1000000000 + (extensionNumber - 1) * 1000 | 120 let enumBase = 1000000000 + (extensionNumber - 1) * 1000 |
| 117 for require in extension.findAll("require"): | 121 for require in extension.findAll("require"): |
| 118 for theenum in require.findAll("enum"): | 122 for theenum in require.findAll("enum"): |
| 119 if theenum.attr("extends") == name: | 123 if theenum.attr("extends") == name: |
| 154 else: | 158 else: |
| 155 values[smartParseInt(value.attr("value"))] = value.attr("name") | 159 values[smartParseInt(value.attr("value"))] = value.attr("name") |
| 156 if values.len > 0: | 160 if values.len > 0: |
| 157 result.add " " & name & "* {.size: sizeof(cint).} = enum" | 161 result.add " " & name & "* {.size: sizeof(cint).} = enum" |
| 158 for (value, name) in tableSorted(values): | 162 for (value, name) in tableSorted(values): |
| 159 let enumEntry = &" {name} = {value}" | 163 var thename = name |
| 164 if name.replace("_", "").toLower() in reservedNames: | |
| 165 thename = thename & "_ENUM" | |
| 166 let enumEntry = &" {thename} = {value}" | |
| 160 result.add enumEntry | 167 result.add enumEntry |
| 161 | 168 |
| 162 # generate bitsets (normal enums in the C API, but bitfield-enums in Nim) | 169 # generate bitsets (normal enums in the C API, but bitfield-enums in Nim) |
| 163 elif node.attr("type") == "bitmask": | 170 elif node.attr("type") == "bitmask": |
| 164 for value in node.findAll("enum"): | 171 for value in node.findAll("enum"): |
| 191 result.add &"""converter BitsetToNumber*(flags: openArray[{name}]): {cApiName} = | 198 result.add &"""converter BitsetToNumber*(flags: openArray[{name}]): {cApiName} = |
| 192 for flag in flags: | 199 for flag in flags: |
| 193 result = {cApiName}(uint(result) or uint(flag))""" | 200 result = {cApiName}(uint(result) or uint(flag))""" |
| 194 result.add "type" | 201 result.add "type" |
| 195 | 202 |
| 196 func serializeStruct(node: XmlNode, root: XmlNode): seq[string] = | 203 func serializeStruct(node: XmlNode): seq[string] = |
| 197 let name = node.attr("name") | 204 let name = node.attr("name") |
| 198 var union = "" | 205 var union = "" |
| 199 if node.attr("category") == "union": | 206 if node.attr("category") == "union": |
| 200 union = "{.union.} " | 207 union = "{.union.} " |
| 201 result.add &" {name}* {union}= object" | 208 result.add &" {name}* {union}= object" |
| 340 " let vulkanLib* = loadLib(\"libvulkan.so.1\")", | 347 " let vulkanLib* = loadLib(\"libvulkan.so.1\")", |
| 341 "when defined(windows):", | 348 "when defined(windows):", |
| 342 " let vulkanLib* = loadLib(\"vulkan-1.dll\")", | 349 " let vulkanLib* = loadLib(\"vulkan-1.dll\")", |
| 343 "if vulkanLib == nil:", | 350 "if vulkanLib == nil:", |
| 344 " raise newException(Exception, \"Unable to load vulkan library\")", | 351 " raise newException(Exception, \"Unable to load vulkan library\")", |
| 352 "func VK_MAKE_API_VERSION*(variant: uint32, major: uint32, minor: uint32, patch: uint32): uint32 {.compileTime.} =", | |
| 353 " (variant shl 29) or (major shl 22) or (minor shl 12) or patch", | |
| 354 "", | |
| 345 "type", | 355 "type", |
| 346 ], | 356 ], |
| 347 "structs": @["type"], | 357 "structs": @["type"], |
| 348 "enums": @["type"], | 358 "enums": @["type"], |
| 349 "commands": @[], | 359 "commands": @[], |
| 364 var outfile = "structs" | 374 var outfile = "structs" |
| 365 if thetype.attr("name") in platformTypes: | 375 if thetype.attr("name") in platformTypes: |
| 366 outfile = "platform/" & platformTypes[thetype.attr("name")] | 376 outfile = "platform/" & platformTypes[thetype.attr("name")] |
| 367 if not (outfile in outputFiles): | 377 if not (outfile in outputFiles): |
| 368 outputFiles[outfile] = @[] | 378 outputFiles[outfile] = @[] |
| 369 outputFiles[outfile].add serializeStruct(thetype, api) | 379 outputFiles[outfile].add serializeStruct(thetype) |
| 370 | 380 |
| 371 # types | 381 # types |
| 372 var headerTypes: Table[string, string] | 382 var headerTypes: Table[string, string] |
| 373 for types in api.findAll("types"): | 383 for types in api.findAll("types"): |
| 374 for thetype in types.findAll("type"): | 384 for thetype in types.findAll("type"): |
| 411 featureloads.add &"load{name}" | 421 featureloads.add &"load{name}" |
| 412 outputFiles["commands"].add &"proc load{name}*() =" | 422 outputFiles["commands"].add &"proc load{name}*() =" |
| 413 for command in feature.findAll("command"): | 423 for command in feature.findAll("command"): |
| 414 outputFiles["commands"].add procLoads[command.attr("name")] | 424 outputFiles["commands"].add procLoads[command.attr("name")] |
| 415 outputFiles["commands"].add "" | 425 outputFiles["commands"].add "" |
| 416 outputFiles["commands"].add ["proc loadAll*() ="] | 426 outputFiles["commands"].add ["proc initVulkan*() ="] |
| 417 for l in featureloads: | 427 for l in featureloads: |
| 418 outputFiles["commands"].add [&" {l}()"] | 428 outputFiles["commands"].add [&" {l}()"] |
| 419 outputFiles["commands"].add "" | 429 outputFiles["commands"].add "" |
| 420 | 430 |
| 421 # for promoted extensions, dependants need to call the load-function of the promoted feature/extension | 431 # for promoted extensions, dependants need to call the load-function of the promoted feature/extension |
| 490 outputFiles[file].add "" | 500 outputFiles[file].add "" |
| 491 | 501 |
| 492 var mainout: seq[string] | 502 var mainout: seq[string] |
| 493 for section in ["basetypes", "enums", "structs", "commands"]: | 503 for section in ["basetypes", "enums", "structs", "commands"]: |
| 494 mainout.add outputFiles[section] | 504 mainout.add outputFiles[section] |
| 505 for platform in api.findAll("platform"): | |
| 506 mainout.add &"when defined({platform.attr(\"protect\")}):" | |
| 507 mainout.add &" include platform/{platform.attr(\"name\")}" | |
| 495 writeFile outdir / &"types.nim", mainout.join("\n") | 508 writeFile outdir / &"types.nim", mainout.join("\n") |
| 496 | 509 |
| 497 for filename, filecontent in outputFiles.pairs: | 510 for filename, filecontent in outputFiles.pairs: |
| 498 if filename.startsWith("platform/"): | 511 if filename.startsWith("platform/"): |
| 499 writeFile outdir / &"{filename}.nim", (@[ | 512 writeFile outdir / &"{filename}.nim", (@[ |
| 500 "import std/dynlib", | |
| 501 "import ../types", | |
| 502 "type" | 513 "type" |
| 503 ] & filecontent).join("\n") | 514 ] & filecontent).join("\n") |
| 504 | 515 |
| 505 when isMainModule: | 516 when isMainModule: |
| 506 main() | 517 main() |
