about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-01-11 09:04:18 -0500
committerDrew DeVault <sir@cmpwn.com>2018-01-11 09:04:18 -0500
commit4074445cbb45dc6ec132e67b7eac9f32dcfd53de (patch)
treeabb2348df84e12f0a781a4e0d29509962d01c756
parentffba56133406027a6a740f9f4454b27134143f0a (diff)
downloadaerc-4074445cbb45dc6ec132e67b7eac9f32dcfd53de.tar.gz
Move worker into account tab
-rw-r--r--cmd/aerc/main.go20
-rw-r--r--ui/account.go31
-rw-r--r--ui/helpers.go30
-rw-r--r--ui/types.go15
-rw-r--r--ui/ui.go15
-rw-r--r--worker/imap/worker.go9
-rw-r--r--worker/types/messages.go2
-rw-r--r--worker/worker.go2
8 files changed, 86 insertions, 38 deletions
diff --git a/cmd/aerc/main.go b/cmd/aerc/main.go
index 420d7a8..e33f158 100644
--- a/cmd/aerc/main.go
+++ b/cmd/aerc/main.go
@@ -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)
 		}
 	}
diff --git a/ui/account.go b/ui/account.go
index 9c16cc5..50f41e4 100644
--- a/ui/account.go
+++ b/ui/account.go
@@ -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))
+}
diff --git a/ui/helpers.go b/ui/helpers.go
index 0b8789e..f2b2adf 100644
--- a/ui/helpers.go
+++ b/ui/helpers.go
@@ -9,13 +9,33 @@ import (
 func TPrintf(geo *Geometry, ref tb.Cell, format string, a ...interface{}) {
 	str := fmt.Sprintf(format, a...)
 	_geo := *geo
+	newline := func() {
+		// TODO: Abort when out of room?
+		geo.Col = _geo.Col
+		geo.Row++
+	}
 	for _, ch := range str {
-		tb.SetCell(geo.Col, geo.Row, ch, ref.Fg, ref.Bg)
-		geo.Col++
-		if geo.Col == _geo.Col+geo.Width {
-			// TODO: Abort when out of room?
+		switch ch {
+		case '\n':
+			newline()
+		case '\r':
 			geo.Col = _geo.Col
-			geo.Row++
+		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
 	}
 }
diff --git a/ui/types.go b/ui/types.go
index 14a91c3..5437642 100644
--- a/ui/types.go
+++ b/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
 }
diff --git a/ui/ui.go b/ui/ui.go
index f01af08..db31696 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -11,7 +11,8 @@ func Initialize(conf *config.AercConfig) (*UIState, error) {
 		Config:       conf,
 		InvalidPanes: InvalidateAll,
 
-		tbEvents: make(chan tb.Event, 10),
+		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
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index 14e4004..080927d 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -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) {
diff --git a/worker/types/messages.go b/worker/types/messages.go
index 845bb86..a4d8ddb 100644
--- a/worker/types/messages.go
+++ b/worker/types/messages.go
@@ -33,7 +33,7 @@ type Ping struct {
 
 type Configure struct {
 	Message
-	Config config.AccountConfig
+	Config *config.AccountConfig
 }
 
 type Connect struct {
diff --git a/worker/worker.go b/worker/worker.go
index da7928e..c8ec622 100644
--- a/worker/worker.go
+++ b/worker/worker.go
@@ -9,7 +9,7 @@ import (
 )
 
 type Worker interface {
-	GetMessage() types.WorkerMessage
+	GetMessages() chan types.WorkerMessage
 	PostAction(types.WorkerMessage)
 	Run()
 }