Change to use HubReq to communicate

This commit is contained in:
Daisuke Maki 2014-07-11 17:14:03 +09:00
parent 8efd69240f
commit c6e9d97f1f
5 changed files with 93 additions and 24 deletions

View file

@ -105,11 +105,11 @@ func init() {
ActionFunc(doSelectAll).Register("SelectAll")
ActionFunc(doSelectVisible).Register("SelectVisible")
ActionFunc(func(i *Input, ev termbox.Event) {
i.StatusMsgCh() <- "ToggleSelectMode is deprecated. Use ToggleRangeMode"
i.SendStatusMsg("ToggleSelectMode is deprecated. Use ToggleRangeMode")
doToggleRangeMode(i, ev)
}).Register("ToggleSelectMode")
ActionFunc(func(i *Input, ev termbox.Event) {
i.StatusMsgCh() <- "CancelSelectMode is deprecated. Use CancelRangeMode"
i.SendStatusMsg("CancelSelectMode is deprecated. Use CancelRangeMode")
doCancelRangeMode(i, ev)
}).Register("CancelSelectMode")
ActionFunc(doToggleRangeMode).Register("ToggleRangeMode")
@ -507,7 +507,7 @@ func doDeleteBackwardChar(i *Input, ev termbox.Event) {
}
func doKonamiCommand(i *Input, ev termbox.Event) {
i.StatusMsgCh() <- "All your filters are blongs to us"
i.SendStatusMsg("All your filters are blongs to us")
}
func makeCombinedAction(actions ...Action) ActionFunc {

4
ctx.go
View file

@ -137,14 +137,14 @@ func (c *Ctx) WaitDone() {
func (c *Ctx) ExecQuery() bool {
if len(c.query) > 0 {
c.QueryCh() <- string(c.query)
c.SendQuery(string(c.query))
return true
}
return false
}
func (c *Ctx) DrawMatches(m []Match) {
c.DrawCh() <- m
c.SendDraw(m)
}
func (c *Ctx) Refresh() {
c.DrawMatches(nil)

View file

@ -5,13 +5,15 @@ type Filter struct {
jobs chan string
}
func (f *Filter) Work(cancel chan struct{}, q string) {
if q == "" {
func (f *Filter) Work(cancel chan struct{}, q HubReq) {
defer q.Done()
query := q.DataString()
if query == "" {
f.DrawMatches(nil)
return
}
f.current = f.Matcher().Match(cancel, q, f.Buffer())
f.StatusMsgCh() <- ""
f.current = f.Matcher().Match(cancel, query, f.Buffer())
f.SendStatusMsg("")
f.selection.Clear()
f.DrawMatches(nil)
}
@ -34,7 +36,7 @@ func (f *Filter) Loop() {
}
previous = make(chan struct{}, 1)
f.StatusMsgCh() <- "Running query..."
f.SendStatusMsg("Running query...")
go f.Work(previous, q)
}
}

89
hub.go
View file

@ -1,39 +1,104 @@
package peco
import "sync"
type Hub struct {
isSync bool
mutex *sync.Mutex
loopCh chan struct{}
queryCh chan string
drawCh chan []Match
statusMsgCh chan string
queryCh chan HubReq
drawCh chan HubReq
statusMsgCh chan HubReq
pagingCh chan PagingRequest
}
type HubReq struct {
data interface{}
replyCh chan struct{}
}
func (hr HubReq) DataInterface() interface{} {
return hr.data
}
func (hr HubReq) DataString() string {
return hr.data.(string)
}
func (hr HubReq) Done() {
if hr.replyCh != nil {
hr.replyCh<-struct{}{}
}
}
func NewHub() *Hub {
return &Hub{
false,
&sync.Mutex{},
make(chan struct{}), // loopCh. You never send messages to this. no point in buffering
make(chan string, 5), // queryCh.
make(chan []Match, 5), // drawCh.
make(chan string, 5), // statusMsgCh
make(chan HubReq, 5), // queryCh.
make(chan HubReq, 5), // drawCh.
make(chan HubReq, 5), // statusMsgCh
make(chan PagingRequest, 5), // pagingCh
}
}
// Batch allows you to synchronously send messages during the
// scope of f() being executed.
func (h *Hub) Batch(f func()) {
// lock during this operation
h.mutex.Lock()
defer h.mutex.Unlock()
// temporarily set isSync = true
o := h.isSync
h.isSync = true
defer func() { h.isSync = o }()
// ignore panics
defer func() { recover() }()
f()
}
// low-level utility
func send(ch chan HubReq, r HubReq, needReply bool) {
if needReply {
r.replyCh = make(chan struct{})
defer func() { <-r.replyCh }()
}
ch <- r
}
func (h *Hub) QueryCh() chan HubReq {
return h.queryCh
}
func (h *Hub) SendQuery(q string) {
send(h.QueryCh(), HubReq{q, nil}, h.isSync)
}
func (h *Hub) LoopCh() chan struct{} {
return h.loopCh
}
func (h *Hub) QueryCh() chan string {
return h.queryCh
}
func (h *Hub) DrawCh() chan []Match {
func (h *Hub) DrawCh() chan HubReq {
return h.drawCh
}
func (h *Hub) StatusMsgCh() chan string {
func (h *Hub) SendDraw(matches []Match) {
send(h.DrawCh(), HubReq{matches, nil}, h.isSync)
}
func (h *Hub) StatusMsgCh() chan HubReq {
return h.statusMsgCh
}
func (h *Hub) SendStatusMsg(q string) {
send(h.StatusMsgCh(), HubReq{q, nil}, h.isSync)
}
func (h *Hub) PagingCh() chan PagingRequest {
return h.pagingCh
}

View file

@ -35,11 +35,13 @@ func (v *View) Loop() {
case <-v.LoopCh():
return
case m := <-v.StatusMsgCh():
v.printStatus(m)
v.printStatus(m.DataString())
m.Done()
case r := <-v.PagingCh():
v.movePage(r)
case lines := <-v.DrawCh():
v.drawScreen(lines)
v.drawScreen(lines.DataInterface().([]Match))
lines.Done()
}
}
}