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