package cli
import
const inputChSize = 128
type loop struct {
inputCh chan event
handleCb handleCb
redrawCb redrawCb
redrawCh chan struct{}
redrawFull bool
redrawMutex *sync.Mutex
returnCh chan loopReturn
}
type loopReturn struct {
buffer string
err error
}
type event interface{}
type redrawCb func(flag redrawFlag)
func (redrawFlag) {}
type redrawFlag uint
const (
fullRedraw redrawFlag = 1 << iota
finalRedraw
)
type handleCb func(event)
func (event) {}
func () *loop {
return &loop{
inputCh: make(chan event, inputChSize),
handleCb: dummyHandleCb,
redrawCb: dummyRedrawCb,
redrawCh: make(chan struct{}, 1),
redrawFull: false,
redrawMutex: new(sync.Mutex),
returnCh: make(chan loopReturn, 1),
}
}
func ( *loop) ( handleCb) {
.handleCb =
}
func ( *loop) ( redrawCb) {
.redrawCb =
}
func ( *loop) ( bool) {
.redrawMutex.Lock()
defer .redrawMutex.Unlock()
if {
.redrawFull = true
}
select {
case .redrawCh <- struct{}{}:
default:
}
}
func ( *loop) ( event) {
.inputCh <-
}
func ( *loop) ( string, error) {
select {
case .returnCh <- loopReturn{, }:
default:
}
}
func ( *loop) () bool {
return len(.returnCh) == 1
}
func ( *loop) () ( string, error) {
for {
var redrawFlag
if .extractRedrawFull() {
|= fullRedraw
}
.redrawCb()
select {
case := <-.inputCh:
:
for {
.handleCb()
select {
case := <-.returnCh:
.redrawCb(finalRedraw)
return .buffer, .err
default:
}
select {
case = <-.inputCh:
default:
break
}
}
case := <-.returnCh:
.redrawCb(finalRedraw)
return .buffer, .err
case <-.redrawCh:
}
}
}
func ( *loop) () bool {
.redrawMutex.Lock()
defer .redrawMutex.Unlock()
:= .redrawFull
.redrawFull = false
return
}