Skip to content

Commit

Permalink
Add INIT macros with default values (#422)
Browse files Browse the repository at this point in the history
  • Loading branch information
eliemichel authored Nov 21, 2024
1 parent e033e45 commit c4ac882
Show file tree
Hide file tree
Showing 8 changed files with 2,298 additions and 15 deletions.
51 changes: 47 additions & 4 deletions gen/cheader.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,27 @@
{{- if eq .Name "webgpu"}}
#include <stdint.h>
#include <stddef.h>
#include <math.h>
{{else}}
#include "webgpu.h"
{{end}}

{{- if eq .Name "webgpu"}}
#define _wgpu_COMMA ,
#if defined(__cplusplus)
# define _wgpu_ENUM_ZERO_INIT(type) type(0)
# if __cplusplus >= 201103L
# define _wgpu_MAKE_INIT_STRUCT(type, value) (type value)
# else
# define _wgpu_MAKE_INIT_STRUCT(type, value) value
# endif
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
# define _wgpu_MAKE_INIT_STRUCT(type, value) ((type) value)
#else
# define _wgpu_MAKE_INIT_STRUCT(type, value) value
# define _wgpu_ENUM_ZERO_INIT(type) (type)0
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
# define _wgpu_MAKE_INIT_STRUCT(type, value) ((type) value)
# else
# define _wgpu_MAKE_INIT_STRUCT(type, value) value
# endif
#endif
{{end}}

Expand Down Expand Up @@ -138,6 +143,9 @@ typedef struct WGPUStringView {
*/
#define WGPU_STRLEN SIZE_MAX

/**
* Initializer for @ref WGPUStringView.
*/
#define WGPU_STRING_VIEW_INIT _wgpu_MAKE_INIT_STRUCT(WGPUStringView, { \
/*.data=*/NULL _wgpu_COMMA \
/*.length=*/WGPU_STRLEN _wgpu_COMMA \
Expand Down Expand Up @@ -294,13 +302,26 @@ typedef struct WGPU{{.Name | PascalCase}}CallbackInfo{{$.ExtSuffix}} {
WGPU_NULLABLE void* userdata1;
WGPU_NULLABLE void* userdata2;
} WGPU{{.Name | PascalCase}}CallbackInfo{{$.ExtSuffix}} WGPU_STRUCTURE_ATTRIBUTE;

/**
* Initializer for @ref WGPU{{.Name | PascalCase}}CallbackInfo{{$.ExtSuffix}}.
*/
#define WGPU_{{.Name | ConstantCase}}_CALLBACK_INFO{{$.ExtSuffix}}_INIT _wgpu_MAKE_INIT_STRUCT(WGPU{{.Name | PascalCase}}CallbackInfo{{$.ExtSuffix}}, { \
/*.nextInChain=*/NULL _wgpu_COMMA \
{{- if eq .Style "callback_mode" }}
/*.mode=*/WGPUCallbackMode_WaitAnyOnly _wgpu_COMMA \
{{- end}}
/*.callback=*/NULL _wgpu_COMMA \
/*.userdata1=*/NULL _wgpu_COMMA \
/*.userdata2=*/NULL _wgpu_COMMA \
})
{{ end}}{{"\n" -}}

/** @} */

{{- "\n"}}
{{- range $struct := .Structs}}
{{- MComment .Doc 0}}
{{- MCommentStruct . 0}}
typedef struct WGPU{{.Name | PascalCase}}{{$.ExtSuffix}} {
{{- if eq .Type "base_in" }}
WGPUChainedStruct const * nextInChain;
Expand All @@ -322,6 +343,28 @@ typedef struct WGPU{{.Name | PascalCase}}{{$.ExtSuffix}} {
{{ StructMember $struct $memberIndex}}
{{- end}}
} WGPU{{.Name | PascalCase}}{{$.ExtSuffix}} WGPU_STRUCTURE_ATTRIBUTE;

/**
* Initializer for @ref WGPU{{.Name | PascalCase}}{{$.ExtSuffix}}.
*/
#define WGPU_{{.Name | ConstantCase}}{{if $.ExtSuffix}}_{{$.ExtSuffix}}{{end}}_INIT _wgpu_MAKE_INIT_STRUCT(WGPU{{.Name | PascalCase}}{{$.ExtSuffix}}, { \
{{- if eq .Type "base_in" "base_out" "base_in_or_out" }}
/*.nextInChain=*/NULL _wgpu_COMMA \
{{- else if eq .Type "extension_in" }}
/*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \
/*.next=*/NULL _wgpu_COMMA \
/*.sType=*/WGPUSType_{{.Name | PascalCase}}{{$.ExtSuffix}} _wgpu_COMMA \
}) _wgpu_COMMA \
{{- else if eq .Type "extension_out" "extension_in_or_out" }}
/*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStructOut, { \
/*.next=*/NULL _wgpu_COMMA \
/*.sType=*/WGPUSType_{{.Name | PascalCase}}{{$.ExtSuffix}} _wgpu_COMMA \
}) _wgpu_COMMA \
{{- end }}
{{- range $memberIndex, $_ := .Members}}
{{ StructMemberInitializer $struct $memberIndex}}
{{- end}}
})
{{ end}}{{"\n" -}}

/** @} */
Expand Down
139 changes: 135 additions & 4 deletions gen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (g *Generator) Gen(dst io.Writer) error {
return ""
}
value, _ := g.EnumValue(prefix, e, entryIndex)
return Comment("`"+value+"`.\n"+v, CommentTypeMultiLine, indent, true)
return Comment("`"+value+"`.\n"+strings.TrimSpace(v), CommentTypeMultiLine, indent, true)
},
"MCommentBitflag": func(v string, indent int, b Bitflag, entryIndex int) string {
if v == "" || strings.TrimSpace(v) == "TODO" {
Expand Down Expand Up @@ -122,12 +122,26 @@ func (g *Generator) Gen(dst io.Writer) error {
s += "\n\nThis is an \\ref OutputString."
}

s += "\n\nDefaults to " + g.DefaultValue(*member, true /* isDocString */) + "."

if member.PassedWithOwnership != nil {
panic("invalid")
}

return Comment(strings.TrimSpace(s), CommentTypeMultiLine, indent, true)
},
"MCommentStruct": func(st *Struct, indent int) string {
var s string

var srcDoc = strings.TrimSpace(st.Doc)
if srcDoc != "" && srcDoc != "TODO" {
s += srcDoc
}

s += "\n\nDefault values can be set using @ref WGPU_" + ConstantCase(st.Name) + "_INIT as initializer."

return Comment(strings.TrimSpace(s), CommentTypeMultiLine, indent, true)
},
"ConstantCase": ConstantCase,
"PascalCase": PascalCase,
"CamelCase": CamelCase,
Expand Down Expand Up @@ -156,9 +170,10 @@ func (g *Generator) Gen(dst io.Writer) error {
}
return "void"
},
"FunctionArgs": g.FunctionArgs,
"CallbackArgs": g.CallbackArgs,
"StructMember": g.StructMember,
"FunctionArgs": g.FunctionArgs,
"CallbackArgs": g.CallbackArgs,
"StructMember": g.StructMember,
"StructMemberInitializer": g.StructMemberInitializer,
})
t, err := t.Parse(tmpl)
if err != nil {
Expand All @@ -178,6 +193,8 @@ func (g *Generator) CValue(s string) (string, error) {
return "UINT32_MAX", nil
case "uint64_max":
return "UINT64_MAX", nil
case "nan":
return "NAN", nil
default:
var num string
var base int
Expand Down Expand Up @@ -446,3 +463,117 @@ func (g *Generator) StructMember(s Struct, memberIndex int) (string, error) {
}
return sb.String(), nil
}

func (g *Generator) StructMemberInitializer(s Struct, memberIndex int) (string, error) {
member := s.Members[memberIndex]
sb := &strings.Builder{}
matches := arrayTypeRegexp.FindStringSubmatch(member.Type)
if len(matches) == 2 {
fmt.Fprintf(sb, "/*.%sCount=*/0 _wgpu_COMMA \\\n", CamelCase(Singularize(member.Name)))
fmt.Fprintf(sb, " /*.%s=*/NULL _wgpu_COMMA \\", CamelCase(member.Name))
} else {
fmt.Fprintf(sb, "/*.%s=*/%s _wgpu_COMMA \\", CamelCase(member.Name), g.DefaultValue(member, false /* isDocString */))
}
return sb.String(), nil
}

func (g *Generator) DefaultValue(member ParameterType, isDocString bool) string {
ref := func(s string) string {
if isDocString {
return "@ref " + s
} else {
return s
}
}
literal := func(s string) string {
if isDocString {
return "`" + s + "`"
} else {
return s
}
}
switch {
case member.Pointer != "":
return literal("NULL")
case strings.HasPrefix(member.Type, "enum."):
if member.Default == "" {
if member.Type == "enum.optional_bool" {
// This Undefined is a special one that is not the zero-value, so that
// a stdbool.h bool cast correctly to WGPUOptionalBool; this means we
// must explicitly initialize it
return ref("WGPUOptionalBool_Undefined")
} else if isDocString {
return "(@ref WGPU" + PascalCase(strings.TrimPrefix(member.Type, "enum.")) + ")0"
} else {
return "_wgpu_ENUM_ZERO_INIT(WGPU" + PascalCase(strings.TrimPrefix(member.Type, "enum.")) + ")"
}
} else {
return ref("WGPU" + PascalCase(strings.TrimPrefix(member.Type, "enum.")) + "_" + PascalCase(member.Default))
}
case strings.HasPrefix(member.Type, "bitflag."):
if member.Default == "" {
return ref("WGPU" + PascalCase(strings.TrimPrefix(member.Type, "bitflag.")) + "_None")
} else {
return ref("WGPU" + PascalCase(strings.TrimPrefix(member.Type, "bitflag.")) + "_" + PascalCase(member.Default))
}
case strings.HasPrefix(member.Type, "struct."):
if member.Optional {
return literal("NULL")
} else {
typ := strings.TrimPrefix(member.Type, "struct.")
return ref("WGPU_" + ConstantCase(typ) + "_INIT")
}
case strings.HasPrefix(member.Type, "callback."):
typ := strings.TrimPrefix(member.Type, "callback.")
return ref("WGPU_" + ConstantCase(typ) + "_CALLBACK_INFO_INIT")
case strings.HasPrefix(member.Type, "object."):
return literal("NULL")
case strings.HasPrefix(member.Type, "array<"):
return literal("NULL")
case member.Type == "out_string", member.Type == "string_with_default_empty", member.Type == "nullable_string":
return ref("WGPU_STRING_VIEW_INIT")
case member.Type == "uint16", member.Type == "uint32", member.Type == "uint64", member.Type == "usize", member.Type == "int32":
if member.Default == "" {
return literal("0")
} else if strings.HasPrefix(member.Default, "constant.") {
return ref("WGPU_" + ConstantCase(strings.TrimPrefix(member.Default, "constant.")))
} else {
return literal(member.Default)
}
case member.Type == "float32":
if member.Default == "" {
return literal("0.f")
} else if strings.HasPrefix(member.Default, "constant.") {
return ref("WGPU_" + ConstantCase(strings.TrimPrefix(member.Default, "constant.")))
} else if strings.Contains(member.Default, ".") {
return literal(member.Default + "f")
} else {
return literal(member.Default + ".f")
}
case member.Type == "float64":
if member.Default == "" {
return literal("0.")
} else if strings.HasPrefix(member.Default, "constant.") {
return ref("WGPU_" + ConstantCase(strings.TrimPrefix(member.Default, "constant.")))
} else {
return literal(member.Default)
}
case member.Type == "bool":
if member.Default == "" {
return literal("0")
} else if strings.HasPrefix(member.Default, "constant.") {
return ref("WGPU_" + ConstantCase(strings.TrimPrefix(member.Default, "constant.")))
} else if member.Default == "true" {
return literal("1")
} else if member.Default == "false" {
return literal("0")
} else {
return member.Default
}
case member.Type == "c_void":
return literal("NULL")
default:
panic("invalid prefix: " + member.Type + " in member " + member.Name)
return ""
}
}
1 change: 1 addition & 0 deletions gen/yml.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type ParameterType struct {
Pointer PointerType `yaml:"pointer"`
Optional bool `yaml:"optional"`
Namespace string `yaml:"namespace"`
Default string `yaml:"default"`
}

type Callback struct {
Expand Down
9 changes: 7 additions & 2 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"enum": [
"usize_max",
"uint32_max",
"uint64_max"
"uint64_max",
"nan"
]
}
]
Expand Down Expand Up @@ -153,6 +154,10 @@
"type": "string",
"description": "Optional property, specifying the external namespace where this type is defined",
"pattern": "^[a-z]+$"
},
"default": {
"type": [ "string", "number", "boolean" ],
"description": "Default value assigned to this parameter when using initializer macro"
}
},
"required": [
Expand Down Expand Up @@ -279,7 +284,7 @@
},
"value": {
"$ref": "#/definitions/Value64",
"description": "An enum of predefined max constants or a 64-bit unsigned integer"
"description": "An enum of predefined max constants or a 64-bit unsigned integer, or float NaN value."
},
"doc": {
"type": "string"
Expand Down
Loading

0 comments on commit c4ac882

Please sign in to comment.