Add support for command batching

This commit is contained in:
Christian Rocha 2020-03-31 16:08:03 -04:00
parent 58a047c2ac
commit 6e769686f1
No known key found for this signature in database
GPG Key ID: D6CC7A16E5878018
1 changed files with 22 additions and 1 deletions

23
tea.go
View File

@ -9,7 +9,7 @@ import (
"github.com/muesli/termenv" "github.com/muesli/termenv"
) )
// Msg represents an action. It's used by Update to update the UI. // Msg represents an action. It's used signal Update to update the UI.
type Msg interface{} type Msg interface{}
// Model contains the updatable data for an application // Model contains the updatable data for an application
@ -18,6 +18,14 @@ type Model interface{}
// Cmd is an IO operation. If it's nil it's considered a no-op. // Cmd is an IO operation. If it's nil it's considered a no-op.
type Cmd func(Model) Msg type Cmd func(Model) Msg
// Batch peforms a bunch of commands concurrently with no ordering guarantees
// about the results.
func Batch(cmds ...Cmd) Cmd {
return func(_ Model) Msg {
return batchMsg(cmds)
}
}
// Sub is an event subscription. If it returns nil it's considered a no-op, // Sub is an event subscription. If it returns nil it's considered a no-op,
// but there's really no reason to have a nil subscription. // but there's really no reason to have a nil subscription.
type Sub func(Model) Msg type Sub func(Model) Msg
@ -78,6 +86,7 @@ type ErrMsg struct {
error error
} }
// String implements String() on the error interface for ErrMsg
func (e ErrMsg) String() string { func (e ErrMsg) String() string {
return e.Error() return e.Error()
} }
@ -104,6 +113,9 @@ func Quit(_ Model) Msg {
// Signals that the program should quit // Signals that the program should quit
type quitMsg struct{} type quitMsg struct{}
// batchMsg is used to perform a bunch of commands
type batchMsg []Cmd
// NewProgram creates a new Program // NewProgram creates a new Program
func NewProgram(init Init, update Update, view View, subs Subscriptions) *Program { func NewProgram(init Init, update Update, view View, subs Subscriptions) *Program {
return &Program{ return &Program{
@ -175,11 +187,20 @@ func (p *Program) Start() error {
for { for {
select { select {
case msg := <-msgs: case msg := <-msgs:
// Handle quit message
if _, ok := msg.(quitMsg); ok { if _, ok := msg.(quitMsg); ok {
close(done) close(done)
return nil return nil
} }
// Process batch commands
if b, ok := msg.(batchMsg); ok {
for _, cmd := range b {
cmds <- cmd
}
}
p.model, cmd = p.update(msg, p.model) // run update p.model, cmd = p.update(msg, p.model) // run update
cmds <- cmd // process command (if any) cmds <- cmd // process command (if any)
subs = p.processSubs(msgs, subs) // check for new and outdated subscriptions subs = p.processSubs(msgs, subs) // check for new and outdated subscriptions