Documentation
¶
Overview ¶
Package present decides when a frame is drawn.
A terminal UI has more reasons to redraw than it has frames worth drawing: a streamed token, a spinner tick, a scroll wheel and a resize can all land inside one refresh interval. The presenter turns that stream of reasons into a paced sequence of draws, and refuses to draw at all while the terminal is still swallowing the last frame.
It is state, not machinery: it owns no goroutine, opens nothing, and writes nothing. Its driver asks what to do and it answers. That is what makes the pacing rules testable without a terminal.
Index ¶
- type Presenter
- func (p *Presenter) DueAt() (time.Time, bool)
- func (p *Presenter) Present(now time.Time, draw func(full bool) (uint64, error)) (bool, error)
- func (p *Presenter) Request()
- func (p *Presenter) RequestBy(now time.Time, minInterval time.Duration) bool
- func (p *Presenter) RequestFull()
- func (p *Presenter) Wrote(seq uint64)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Presenter ¶
type Presenter struct {
// contains filtered or unexported fields
}
Presenter tracks whether a frame is owed, whether one is still in flight, and when the next one may go.
Not safe for concurrent use. It belongs to the driver that draws, and the whole point of a single owner is that "is a frame in flight" has one answer.
func (*Presenter) DueAt ¶
DueAt is when a turned-away throttled request becomes allowed, if one is pending.
A driver that parks until something happens has to know to wake then, or the last update of a burst is never drawn.
func (*Presenter) Present ¶
Present draws the owed frame, if one is owed and the terminal is not still busy with the last, and reports whether it drew.
draw is given whether this frame must be a repaint from scratch, and returns the writer sequence its bytes were queued under — zero when it queued nothing. A frame that reached the writer becomes the one being waited for, so the next request coalesces instead of piling a second frame behind the first.
A failed draw does not satisfy the request. Its full-repaint requirement and due time remain pending so a caller that can recover may try again; a caller for which frame construction is fatal can return the error without the presenter recording a frame that never existed.
func (*Presenter) Request ¶
func (p *Presenter) Request()
Request asks for a frame, now. It never draws: it records that one is owed, and cancels any wait a throttled request had put in the way.
func (*Presenter) RequestBy ¶
RequestBy asks for a frame no sooner than minInterval after the last one, and reports whether it may be drawn straight away.
It is for sources that fire faster than a terminal can usefully be redrawn — a token stream, a scroll wheel held down. A request too soon still owes a frame: the interval decides when it is drawn, not whether. It arms Presenter.DueAt so a driver that parks knows when to wake, and Presenter.Present holds the frame until then.
func (*Presenter) RequestFull ¶
func (p *Presenter) RequestFull()
RequestFull asks for a frame drawn from scratch, for when what the terminal is showing can no longer be trusted.