This commit is contained in:
Daisuke Maki 2014-07-12 16:32:09 +09:00
parent 8c1bcab562
commit d2c422250e

33
hub.go
View file

@ -2,6 +2,9 @@ package peco
import "sync"
// Hub acts as the messaging hub between components -- that is,
// it controls how the communication that goes through channels
// are handled.
type Hub struct {
isSync bool
mutex *sync.Mutex
@ -12,25 +15,38 @@ type Hub struct {
pagingCh chan HubReq
}
// HubReq is a wrapper around the actual requst value that needs
// to be passed. It contains an optional channel field which can
// be filled to force synchronous communication between the
// sender and receiver
type HubReq struct {
data interface{}
replyCh chan struct{}
}
// DataInterface returns the underlying data as interface{}
func (hr HubReq) DataInterface() interface{} {
return hr.data
}
// DataString returns the underlying data as a string. Panics
// if type conversion fails.
func (hr HubReq) DataString() string {
return hr.data.(string)
}
// Done marks the request as done. If Hub is operating in
// asynchronous mode (default), it's a no op. Otherwise it
// sends a message back the reply channel to finish up the
// synchronous communication
func (hr HubReq) Done() {
if hr.replyCh != nil {
hr.replyCh <- struct{}{}
if hr.replyCh == nil {
return
}
hr.replyCh <- struct{}{}
}
// NewHub creates a new Hub struct
func NewHub() *Hub {
return &Hub{
false,
@ -71,42 +87,55 @@ func send(ch chan HubReq, r HubReq, needReply bool) {
ch <- r
}
// QueryCh returns the underlying channel for queries
func (h *Hub) QueryCh() chan HubReq {
return h.queryCh
}
// SendQuery sends the query string to be processed by the Filter
func (h *Hub) SendQuery(q string) {
send(h.QueryCh(), HubReq{q, nil}, h.isSync)
}
// LoopCh returns the channel to control the main execution loop.
// Nothing should ever be sent through this channel. The only way
// the channel communicates anything to its receivers is when
// it is closed -- which is when peco is done.
func (h *Hub) LoopCh() chan struct{} {
return h.loopCh
}
// DrawCh returns the channel to redraw the terminal display
func (h *Hub) DrawCh() chan HubReq {
return h.drawCh
}
// SendDraw sends a request to redraw the terminal display
func (h *Hub) SendDraw(matches []Match) {
send(h.DrawCh(), HubReq{matches, nil}, h.isSync)
}
// StatusMsgCh returns the channel to update the status message
func (h *Hub) StatusMsgCh() chan HubReq {
return h.statusMsgCh
}
// SendStatusMsg sends a string to be displayed in the status message
func (h *Hub) SendStatusMsg(q string) {
send(h.StatusMsgCh(), HubReq{q, nil}, h.isSync)
}
// PagingCh returns the channel to page through the results
func (h *Hub) PagingCh() chan HubReq {
return h.pagingCh
}
// SendPaging sends a request to move the cursor around
func (h *Hub) SendPaging(x PagingRequest) {
send(h.PagingCh(), HubReq{x, nil}, h.isSync)
}
// Stop closes the LoopCh so that peco shutsdown
func (h *Hub) Stop() {
close(h.LoopCh())
}