// Used to send screen events from separate goroutine to main event loop
eventschantcell.Event
// Used to send primitive updates from separate goroutines to the main event loop
updateschanfunc()
}
// NewApplication creates and returns a new application.
funcNewApplication()*Application{
return&Application{}
return&Application{
events:make(chantcell.Event,100),
updates:make(chanfunc(),100),
}
}
// SetInputCapture sets a function which captures all key events before they are
@ -136,7 +145,8 @@ func (a *Application) Run() error {
a.Unlock()
a.Draw()
// Start event loop.
// Separate loop to wait for screen events
gofunc(){
for{
// Do not poll events during suspend mode
a.suspendMutex.Lock()
@ -145,15 +155,25 @@ func (a *Application) Run() error {
a.RUnlock()
ifscreen==nil{
a.suspendMutex.Unlock()
// send signal to stop main event loop
a.QueueEvent(nil)
break
}
// Wait for next event.
event:=a.screen.PollEvent()
a.QueueEvent(screen.PollEvent())
a.suspendMutex.Unlock()
}
}()
// Start event loop.
loop:
for{
select{
caseevent:=<-a.events:
ifevent==nil{
// The screen was finalized. Exit the loop.
break
breakloop
}
switchevent:=event.(type){
@ -166,7 +186,7 @@ func (a *Application) Run() error {
ifa.inputCapture!=nil{
event=a.inputCapture(event)
ifevent==nil{
break// Don't forward event.
breakloop// Don't forward event.
}
}
@ -191,6 +211,12 @@ func (a *Application) Run() error {
screen.Clear()
a.Draw()
}
caseupdater:=<-a.updates:
updater()
a.Draw()
}
}
returnnil
@ -404,3 +430,15 @@ func (a *Application) GetFocus() Primitive {
defera.RUnlock()
returna.focus
}
// QueueUpdate is used to synchronize changes to primitives by carrying an update function from separate goroutine to the Application event loop via channel