2026-03-04 21:11:49 +01:00
|
|
|
package times
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"sort"
|
2026-03-04 21:22:35 +01:00
|
|
|
"time"
|
2026-03-04 21:11:49 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type clockState struct {
|
2026-03-04 21:22:35 +01:00
|
|
|
current time.Time
|
|
|
|
|
chans map[time.Time][]chan<- time.Time
|
2026-03-04 21:11:49 +01:00
|
|
|
chantlist []time.Time
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type test struct {
|
|
|
|
|
state chan clockState
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func makeTestClock(initial time.Time) test {
|
|
|
|
|
s := make(chan clockState, 1)
|
|
|
|
|
s <- clockState{
|
|
|
|
|
current: initial,
|
2026-03-04 21:22:35 +01:00
|
|
|
chans: make(map[time.Time][]chan<- time.Time),
|
2026-03-04 21:11:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return test{state: s}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func triggerChans(s clockState) clockState {
|
|
|
|
|
for len(s.chantlist) > 0 && !s.chantlist[0].After(s.current) {
|
|
|
|
|
var ct time.Time
|
|
|
|
|
ct, s.chantlist = s.chantlist[0], s.chantlist[1:]
|
|
|
|
|
for _, c := range s.chans[ct] {
|
|
|
|
|
c <- s.current
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete(s.chans, ct)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t test) now() time.Time {
|
|
|
|
|
s := <-t.state
|
|
|
|
|
defer func() {
|
|
|
|
|
t.state <- s
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
return s.current
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t test) after(d time.Duration) <-chan time.Time {
|
|
|
|
|
s := <-t.state
|
|
|
|
|
defer func() {
|
|
|
|
|
t.state <- s
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
c := make(chan time.Time, 1)
|
|
|
|
|
ct := s.current.Add(d)
|
|
|
|
|
if !ct.After(s.current) {
|
|
|
|
|
c <- s.current
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, ctset := s.chans[ct]
|
|
|
|
|
s.chans[ct] = append(s.chans[ct], c)
|
|
|
|
|
if !ctset {
|
|
|
|
|
s.chantlist = append(s.chantlist, ct)
|
|
|
|
|
sort.Slice(s.chantlist, func(i, j int) bool {
|
|
|
|
|
return s.chantlist[i].Before(s.chantlist[j])
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t test) pass(d time.Duration) {
|
|
|
|
|
s := <-t.state
|
|
|
|
|
defer func() {
|
|
|
|
|
t.state <- s
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
if d < 0 {
|
|
|
|
|
d = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s.current = s.current.Add(d)
|
|
|
|
|
s = triggerChans(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t test) jump(to time.Time) {
|
|
|
|
|
s := <-t.state
|
|
|
|
|
defer func() {
|
|
|
|
|
t.state <- s
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
if to.Before(s.current) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s.current = to
|
|
|
|
|
s = triggerChans(s)
|
|
|
|
|
}
|
2026-03-05 18:39:54 +01:00
|
|
|
|
|
|
|
|
func (t test) waiting() int {
|
|
|
|
|
s := <-t.state
|
|
|
|
|
defer func() {
|
|
|
|
|
t.state <- s
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
return len(s.chantlist)
|
|
|
|
|
}
|