1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package acp
import "time"
// SpinnerPeriod is how long one frame of the spinner lasts. Eight frames a
// second reads as motion without drawing attention away from the text.
const SpinnerPeriod = 120 * time.Millisecond
// spinnerFrames are the braille dots every terminal spinner uses. They are one
// column wide, which matters: a frame that changed width would shift the words
// beside it on every tick.
var spinnerFrames = []rune("⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏")
// Spinner returns the frame to draw at a moment.
//
// It is a function of the clock rather than of a counter somebody increments,
// so drawing stays a pure function of state — the same rule the rest of this
// editor follows, and what lets a test assert on a frame without waiting for
// one. Nothing has to be reset when a turn starts, and two windows thinking at
// once turn in step.
//
// view.ruleLabel() // " ⠙ thinking — Esc stops it "
func Spinner(at time.Time) rune {
frame := at.UnixNano() / int64(SpinnerPeriod)
return spinnerFrames[int(frame%int64(len(spinnerFrames)))]
}
|