template.go RawHistoryFolder
1package scanner
2
3// protocolTemplate is the template for generating WLTurbo-backed Go bindings.
4//
5// Generated objects embed wl.BaseProxy, send every request through
6// wl.Context.RequestArgs (typed arguments, no interface boxing; it owns
7// version checks, child registration and FD cleanup), and dispatch typed
8// events to registered handlers. Nothing in the generated code opens a
9// socket or frames messages itself: that is the transport's job.
10const protocolTemplate = `// Code generated by wlturbo-scanner. DO NOT EDIT.
11// Protocol: {{.Protocol}}
12// Source: {{.Source}}
13{{if .Copyright}}
14// Upstream protocol copyright and license:
15{{.Copyright}}{{end}}
16package {{.Package}}
17
18{{.ImportBlock}}
19
20{{range .Constants}}
21// {{.Name}} is the {{.Enum}} {{.Entry}} value.
22const {{.Name}}{{if .Type}} {{.Type}}{{end}} = {{.Value}}
23{{- end}}
24{{range .Interfaces}}
25{{- $iface := .}}
26
27// {{$iface.GoName}}Interface is the protocol interface name.
28const {{$iface.GoName}}Interface = "{{$iface.Name}}"
29
30// {{$iface.GoName}} is the generated binding for {{$iface.Name}} version {{$iface.Version}}.
31type {{$iface.GoName}} struct {
32 wl.BaseProxy
33{{- if $iface.HasEvents}}
34 // handlersMu guards the handler slices: a client may register or replace
35 // handlers while another goroutine dispatches events.
36 handlersMu sync.Mutex
37{{- end}}
38{{- range $iface.Events}}
39 {{.HandlerField}} []func({{.HandlerParams}})
40{{- end}}
41}
42
43// New{{$iface.GoName}} returns an unbound {{$iface.GoName}}.
44func New{{$iface.GoName}}(ctx *wl.Context) *{{$iface.GoName}} {
45 obj := &{{$iface.GoName}}{}
46 obj.SetContext(ctx)
47 ctx.Register(obj)
48 return obj
49}
50{{- range $iface.Requests}}
51
52{{- if .Doc}}
53// {{.Doc}}
54{{- end}}
55func (o *{{$iface.GoName}}) {{.GoName}}({{.Params}}) {{.Results}} {
56{{- range .ArgPreparations}}
57 {{.}}
58{{- end}}
59{{- if .CreatesChild}}
60{{- if .ChildFactory}}
61 {{.ChildVar}} := {{.ChildFactory}}(o.Context())
62{{- else}}
63 {{.ChildVar}} := &{{.ChildType}}{}
64 {{.ChildVar}}.SetContext(o.Context())
65{{- end}}
66{{- end}}
67 if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: {{.Opcode}}, Name: "{{$iface.Name}}.{{.Name}}"
68 {{- if gt .Since 1}}, Since: {{.Since}}{{end}}
69 {{- if .Destructor}}, Destructor: true{{end}}
70 {{- if .CreatesChild}}, Child: {{.ChildVar}}{{end}}
71 {{- if .HasFDs}}, FDs: []int{ {{- .FDList -}} }{{end}}}{{.ArgList}}); err != nil {
72 return {{.ErrorReturn}}
73 }
74{{- if .CreatesChild}}
75 return {{.ChildVar}}, nil
76{{- else}}
77 return nil
78{{- end}}
79}
80{{- end}}
81{{- range $iface.Events}}
82
83// On{{.GoName}} registers a handler for the {{.Name}} event.
84//
85// Handlers are appended, so a second call adds another handler rather than
86// replacing the first. Registration is safe while another goroutine dispatches.
87func (o *{{$iface.GoName}}) On{{.GoName}}(handler func({{.HandlerParams}})) {
88 if handler == nil { return }
89 o.handlersMu.Lock()
90 defer o.handlersMu.Unlock()
91 o.{{.HandlerField}} = append(o.{{.HandlerField}}, handler)
92}
93
94// {{.HandlerAccessor}} returns the handlers registered for {{.Name}}, taken
95// under the lock so a handler may register another handler while events are
96// being dispatched.
97func (o *{{$iface.GoName}}) {{.HandlerAccessor}}() []func({{.HandlerParams}}) {
98 o.handlersMu.Lock()
99 defer o.handlersMu.Unlock()
100 return o.{{.HandlerField}}
101}
102{{- end}}
103
104// EventSignature returns the declared event argument types in wire order.
105func (o *{{$iface.GoName}}) EventSignature(opcode uint16) (string, bool) {
106 switch opcode {
107 {{- range $iface.SignatureCases}}
108 case {{.Opcode}}: return "{{.Signature}}", true
109 {{- end}}
110 default: return "", false
111 }
112}
113
114// Dispatch decodes one event on {{$iface.Name}} and calls the registered handlers.
115func (o *{{$iface.GoName}}) Dispatch(event *wl.Event) {
116 switch event.Opcode {
117{{- range $iface.Events}}
118 case {{.Opcode}}: // {{.Name}}
119{{- range .DecodeLines}}
120 {{.}}
121{{- end}}
122 {{if .HasFD}}{{range .FDNames}}owned{{.}} := {{.}}; defer owned{{.}}.Close()
123 {{end}}{{end}}
124 for i, handler := range o.{{.HandlerAccessor}}() {
125 {{- if .HasFD}}
126 if i > 0 { {{range .FDNames}}{{.}} = nil; {{end}} }
127 {{- else}}
128 _ = i
129 {{- end}}
130 handler({{.HandlerArgs}})
131 }
132{{- if .ServerDestroy}}
133 o.Context().Unregister(o)
134{{- end}}
135{{- end}}
136 default:
137 }
138}
139{{end}}
140`