github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/compiler/natives/src/time/time.go (about) 1 //go:build js 2 // +build js 3 4 package time 5 6 import ( 7 "runtime" 8 9 "github.com/gopherjs/gopherjs/js" 10 ) 11 12 // Make sure time.Unix func and time.Time struct it returns are always included with this package (despite DCE), 13 // because they're needed for internalization/externalization of time.Time/Date. See issue https://github.com/gopherjs/gopherjs/issues/279. 14 func init() { 15 // avoid dead code elimination 16 var _ Time = Unix(0, 0) 17 } 18 19 type runtimeTimer struct { 20 i int32 21 when int64 22 period int64 23 f func(interface{}, uintptr) 24 arg interface{} 25 seq uintptr 26 timeout *js.Object 27 active bool 28 } 29 30 func now() (sec int64, nsec int32, mono int64) { 31 n := runtimeNano() 32 return n / int64(Second), int32(n % int64(Second)), n 33 } 34 35 func Sleep(d Duration) { 36 c := make(chan struct{}) 37 js.Global.Call("$setTimeout", js.InternalObject(func() { close(c) }), int(d/Millisecond)) 38 <-c 39 } 40 41 func startTimer(t *runtimeTimer) { 42 t.active = true 43 diff := (t.when - runtimeNano()) / int64(Millisecond) 44 if diff > 1<<31-1 { // math.MaxInt32 45 return 46 } 47 if diff < 0 { 48 diff = 0 49 } 50 t.timeout = js.Global.Call("$setTimeout", js.InternalObject(func() { 51 t.active = false 52 if t.period != 0 { 53 t.when += t.period 54 startTimer(t) 55 } 56 go t.f(t.arg, 0) 57 }), diff+1) 58 } 59 60 func stopTimer(t *runtimeTimer) bool { 61 js.Global.Call("clearTimeout", t.timeout) 62 wasActive := t.active 63 t.active = false 64 return wasActive 65 } 66 67 func modTimer(t *runtimeTimer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) { 68 stopTimer(t) 69 t.when = when 70 t.period = period 71 t.f = f 72 t.arg = arg 73 t.seq = seq 74 startTimer(t) 75 } 76 77 func resetTimer(t *runtimeTimer, when int64) bool { 78 wasActive := t.active 79 modTimer(t, when, t.period, t.f, t.arg, t.seq) 80 return wasActive 81 } 82 83 func forceZipFileForTesting(zipOnly bool) { 84 } 85 86 var zoneSources = []string{ 87 runtime.GOROOT() + "/lib/time/zoneinfo.zip", 88 } 89 90 // indexByte is copied from strings package to avoid importing it (since the real time package doesn't). 91 func indexByte(s string, c byte) int { 92 return js.InternalObject(s).Call("indexOf", js.Global.Get("String").Call("fromCharCode", c)).Int() 93 }