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