...
Source file src/syscall/js/func.go
1
2
3
4
5
6
7 package js
8
9 import "sync"
10
11 var (
12 funcsMu sync.Mutex
13 funcs = make(map[uint32]func(Value, []Value) interface{})
14 nextFuncID uint32 = 1
15 )
16
17 var _ Wrapper = Func{}
18
19
20 type Func struct {
21 Value
22 id uint32
23 }
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 func FuncOf(fn func(this Value, args []Value) interface{}) Func {
39 funcsMu.Lock()
40 id := nextFuncID
41 nextFuncID++
42 funcs[id] = fn
43 funcsMu.Unlock()
44 return Func{
45 id: id,
46 Value: jsGo.Call("_makeFuncWrapper", id),
47 }
48 }
49
50
51
52 func (c Func) Release() {
53 funcsMu.Lock()
54 delete(funcs, c.id)
55 funcsMu.Unlock()
56 }
57
58
59 func setEventHandler(fn func())
60
61 func init() {
62 setEventHandler(handleEvent)
63 }
64
65 func handleEvent() {
66 cb := jsGo.Get("_pendingEvent")
67 if cb == Null() {
68 return
69 }
70 jsGo.Set("_pendingEvent", Null())
71
72 id := uint32(cb.Get("id").Int())
73 if id == 0 {
74 select {}
75 }
76 funcsMu.Lock()
77 f, ok := funcs[id]
78 funcsMu.Unlock()
79 if !ok {
80 Global().Get("console").Call("error", "call to released function")
81 return
82 }
83
84 this := cb.Get("this")
85 argsObj := cb.Get("args")
86 args := make([]Value, argsObj.Length())
87 for i := range args {
88 args[i] = argsObj.Index(i)
89 }
90 result := f(this, args)
91 cb.Set("result", result)
92 }
93
View as plain text