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  }