Move worker into account tab
This commit is contained in:
parent
ffba561334
commit
4074445cbb
8 changed files with 86 additions and 38 deletions
|
@ -5,8 +5,6 @@ import (
|
|||
|
||||
"git.sr.ht/~sircmpwn/aerc2/config"
|
||||
"git.sr.ht/~sircmpwn/aerc2/ui"
|
||||
"git.sr.ht/~sircmpwn/aerc2/worker"
|
||||
"git.sr.ht/~sircmpwn/aerc2/worker/types"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -19,27 +17,15 @@ func main() {
|
|||
panic(err)
|
||||
}
|
||||
defer _ui.Close()
|
||||
var workers []worker.Worker
|
||||
for _, account := range conf.Accounts {
|
||||
work, err := worker.NewWorker(account.Source)
|
||||
tab, err := ui.NewAccountTab(&account)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go work.Run()
|
||||
work.PostAction(types.Configure{Config: account})
|
||||
workers = append(workers, work)
|
||||
// TODO: Give tabs ownership over their workers
|
||||
_ui.AddTab(ui.NewAccountTab(&account, &work))
|
||||
_ui.AddTab(tab)
|
||||
}
|
||||
for !_ui.Exit {
|
||||
activity := false
|
||||
for _, worker := range workers {
|
||||
if msg := worker.GetMessage(); msg != nil {
|
||||
activity = true
|
||||
}
|
||||
}
|
||||
activity = _ui.Tick() || activity
|
||||
if !activity {
|
||||
if !_ui.Tick() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,35 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
tb "github.com/nsf/termbox-go"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc2/config"
|
||||
"git.sr.ht/~sircmpwn/aerc2/worker"
|
||||
"git.sr.ht/~sircmpwn/aerc2/worker/types"
|
||||
)
|
||||
|
||||
type AccountTab struct {
|
||||
Config *config.AccountConfig
|
||||
Worker *worker.Worker
|
||||
Worker worker.Worker
|
||||
Parent *UIState
|
||||
|
||||
counter int
|
||||
log []string
|
||||
}
|
||||
|
||||
func NewAccountTab(conf *config.AccountConfig, work *worker.Worker) *AccountTab {
|
||||
func NewAccountTab(conf *config.AccountConfig) (*AccountTab, error) {
|
||||
work, err := worker.NewWorker(conf.Source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go work.Run()
|
||||
work.PostAction(types.Configure{Config: conf})
|
||||
return &AccountTab{
|
||||
Config: conf,
|
||||
Worker: work,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (acc *AccountTab) Name() string {
|
||||
|
@ -32,13 +42,26 @@ func (acc *AccountTab) SetParent(parent *UIState) {
|
|||
|
||||
func (acc *AccountTab) Render(at Geometry) {
|
||||
cell := tb.Cell{
|
||||
Ch: ' ',
|
||||
Fg: tb.ColorDefault,
|
||||
Bg: tb.ColorDefault,
|
||||
}
|
||||
TPrintf(&at, cell, "%s %d", acc.Name(), acc.counter)
|
||||
TFill(at, cell)
|
||||
TPrintf(&at, cell, "%s %d\n", acc.Name(), acc.counter)
|
||||
for _, str := range acc.log {
|
||||
TPrintf(&at, cell, "%s\n", str)
|
||||
}
|
||||
acc.counter++
|
||||
if acc.counter%10000 == 0 {
|
||||
acc.counter = 0
|
||||
}
|
||||
acc.Parent.InvalidateFrom(acc)
|
||||
}
|
||||
|
||||
func (acc *AccountTab) GetChannel() chan types.WorkerMessage {
|
||||
return acc.Worker.GetMessages()
|
||||
}
|
||||
|
||||
func (acc *AccountTab) HandleMessage(msg types.WorkerMessage) {
|
||||
acc.log = append(acc.log, fmt.Sprintf("<- %T", msg))
|
||||
}
|
||||
|
|
|
@ -9,13 +9,33 @@ import (
|
|||
func TPrintf(geo *Geometry, ref tb.Cell, format string, a ...interface{}) {
|
||||
str := fmt.Sprintf(format, a...)
|
||||
_geo := *geo
|
||||
for _, ch := range str {
|
||||
tb.SetCell(geo.Col, geo.Row, ch, ref.Fg, ref.Bg)
|
||||
geo.Col++
|
||||
if geo.Col == _geo.Col+geo.Width {
|
||||
newline := func() {
|
||||
// TODO: Abort when out of room?
|
||||
geo.Col = _geo.Col
|
||||
geo.Row++
|
||||
}
|
||||
for _, ch := range str {
|
||||
switch ch {
|
||||
case '\n':
|
||||
newline()
|
||||
case '\r':
|
||||
geo.Col = _geo.Col
|
||||
default:
|
||||
tb.SetCell(geo.Col, geo.Row, ch, ref.Fg, ref.Bg)
|
||||
geo.Col++
|
||||
if geo.Col == _geo.Col+geo.Width {
|
||||
newline()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TFill(geo Geometry, ref tb.Cell) {
|
||||
_geo := geo
|
||||
for ; geo.Row < geo.Height; geo.Row++ {
|
||||
for ; geo.Col < geo.Width; geo.Col++ {
|
||||
tb.SetCell(geo.Col, geo.Row, ref.Ch, ref.Fg, ref.Bg)
|
||||
}
|
||||
geo.Col = _geo.Col
|
||||
}
|
||||
}
|
||||
|
|
15
ui/types.go
15
ui/types.go
|
@ -4,20 +4,19 @@ import (
|
|||
tb "github.com/nsf/termbox-go"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc2/config"
|
||||
"git.sr.ht/~sircmpwn/aerc2/worker/types"
|
||||
)
|
||||
|
||||
const (
|
||||
Valid = 0
|
||||
InvalidateTabList = 1 << iota
|
||||
InvalidateTabView
|
||||
InvalidateSidebar
|
||||
InvalidateStatusBar
|
||||
)
|
||||
|
||||
const (
|
||||
InvalidateAll = InvalidateTabList |
|
||||
InvalidateTabView |
|
||||
InvalidateSidebar |
|
||||
InvalidateStatusBar
|
||||
)
|
||||
|
||||
|
@ -34,6 +33,16 @@ type AercTab interface {
|
|||
SetParent(parent *UIState)
|
||||
}
|
||||
|
||||
type WorkerListener interface {
|
||||
GetChannel() chan types.WorkerMessage
|
||||
HandleMessage(msg types.WorkerMessage)
|
||||
}
|
||||
|
||||
type wrappedMessage struct {
|
||||
msg types.WorkerMessage
|
||||
listener WorkerListener
|
||||
}
|
||||
|
||||
type UIState struct {
|
||||
Config *config.AercConfig
|
||||
Exit bool
|
||||
|
@ -57,4 +66,6 @@ type UIState struct {
|
|||
}
|
||||
|
||||
tbEvents chan tb.Event
|
||||
// Aggregate channel for all worker messages
|
||||
workerEvents chan wrappedMessage
|
||||
}
|
||||
|
|
13
ui/ui.go
13
ui/ui.go
|
@ -12,6 +12,7 @@ func Initialize(conf *config.AercConfig) (*UIState, error) {
|
|||
InvalidPanes: InvalidateAll,
|
||||
|
||||
tbEvents: make(chan tb.Event, 10),
|
||||
workerEvents: make(chan wrappedMessage),
|
||||
}
|
||||
if err := tb.Init(); err != nil {
|
||||
return nil, err
|
||||
|
@ -33,6 +34,16 @@ func (state *UIState) Close() {
|
|||
func (state *UIState) AddTab(tab AercTab) {
|
||||
tab.SetParent(state)
|
||||
state.Tabs = append(state.Tabs, tab)
|
||||
if listener, ok := tab.(WorkerListener); ok {
|
||||
go (func() {
|
||||
for msg := range listener.GetChannel() {
|
||||
state.workerEvents <- wrappedMessage{
|
||||
msg: msg,
|
||||
listener: listener,
|
||||
}
|
||||
}
|
||||
})()
|
||||
}
|
||||
}
|
||||
|
||||
func (state *UIState) Invalidate(what uint) {
|
||||
|
@ -67,6 +78,8 @@ func (state *UIState) Tick() bool {
|
|||
case tb.EventResize:
|
||||
state.Invalidate(InvalidateAll)
|
||||
}
|
||||
case msg := <-state.workerEvents:
|
||||
msg.listener.HandleMessage(msg.msg)
|
||||
default:
|
||||
// no-op
|
||||
break
|
||||
|
|
|
@ -18,13 +18,8 @@ func NewIMAPWorker() *IMAPWorker {
|
|||
}
|
||||
}
|
||||
|
||||
func (w *IMAPWorker) GetMessage() types.WorkerMessage {
|
||||
select {
|
||||
case msg := <-w.messages:
|
||||
return msg
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
func (w *IMAPWorker) GetMessages() chan types.WorkerMessage {
|
||||
return w.messages
|
||||
}
|
||||
|
||||
func (w *IMAPWorker) PostAction(msg types.WorkerMessage) {
|
||||
|
|
|
@ -33,7 +33,7 @@ type Ping struct {
|
|||
|
||||
type Configure struct {
|
||||
Message
|
||||
Config config.AccountConfig
|
||||
Config *config.AccountConfig
|
||||
}
|
||||
|
||||
type Connect struct {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
type Worker interface {
|
||||
GetMessage() types.WorkerMessage
|
||||
GetMessages() chan types.WorkerMessage
|
||||
PostAction(types.WorkerMessage)
|
||||
Run()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue