Block main event loop with mutex during Suspend() call

This commit is contained in:
Konstantin Vorobyev 2018-06-20 16:54:24 +02:00
parent 306abd9cb9
commit 2ac0e9e086
1 changed files with 11 additions and 16 deletions

View File

@ -41,8 +41,8 @@ type Application struct {
// was drawn.
afterDraw func(screen tcell.Screen)
// If this value is true, the application has entered suspended mode.
suspended bool
// Used for events loop lock during Suspend()
suspendMutex sync.Mutex
}
// NewApplication creates and returns a new application.
@ -103,28 +103,20 @@ func (a *Application) Run() error {
// Start event loop.
for {
// Do not poll events during suspend mode
a.suspendMutex.Lock()
a.Lock()
screen := a.screen
if a.suspended {
a.suspended = false // Clear previous suspended flag.
}
a.Unlock()
if screen == nil {
a.suspendMutex.Unlock()
break
}
// Wait for next event.
event := a.screen.PollEvent()
a.suspendMutex.Unlock()
if event == nil {
a.Lock()
if a.suspended {
// This screen was renewed due to suspended mode.
a.suspended = false
a.Unlock()
continue // Resume.
}
a.Unlock()
// The screen was finalized. Exit the loop.
break
}
@ -190,14 +182,14 @@ func (a *Application) Stop() {
func (a *Application) Suspend(f func()) bool {
a.Lock()
if a.suspended || a.screen == nil {
if a.screen == nil {
// Application is already suspended.
a.Unlock()
return false
}
// Enter suspended mode.
a.suspended = true
a.suspendMutex.Lock()
a.Unlock()
a.Stop()
@ -217,10 +209,12 @@ func (a *Application) Suspend(f func()) bool {
var err error
a.screen, err = tcell.NewScreen()
if err != nil {
a.suspendMutex.Unlock()
a.Unlock()
panic(err)
}
if err = a.screen.Init(); err != nil {
a.suspendMutex.Unlock()
a.Unlock()
panic(err)
}
@ -228,6 +222,7 @@ func (a *Application) Suspend(f func()) bool {
a.Draw()
// Continue application loop.
a.suspendMutex.Unlock()
return true
}