|
|
|
@ -304,7 +304,7 @@ func (a *Application) Run() error {
|
|
|
|
|
a.Unlock() |
|
|
|
|
a.draw() |
|
|
|
|
|
|
|
|
|
// Separate loop to wait for screen events.
|
|
|
|
|
// Separate loop to wait for screen replacement events.
|
|
|
|
|
var wg sync.WaitGroup |
|
|
|
|
wg.Add(1) |
|
|
|
|
go func() { |
|
|
|
@ -319,14 +319,6 @@ func (a *Application) Run() error {
|
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Wait for next event and queue it.
|
|
|
|
|
event := screen.PollEvent() |
|
|
|
|
if event != nil { |
|
|
|
|
// Regular event. Queue.
|
|
|
|
|
a.QueueEvent(event) |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// A screen was finalized (event is nil). Wait for a new screen.
|
|
|
|
|
screen = <-a.screenReplacement |
|
|
|
|
if screen == nil { |
|
|
|
@ -436,32 +428,38 @@ func (a *Application) Run() error {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Start event loop.
|
|
|
|
|
EventLoop: |
|
|
|
|
semaphore := &sync.Mutex{} |
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
|
for update := range a.updates { |
|
|
|
|
semaphore.Lock() |
|
|
|
|
update() |
|
|
|
|
semaphore.Unlock() |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
|
|
|
|
|
// Start screen event loop.
|
|
|
|
|
for { |
|
|
|
|
// Handle events before executing updates
|
|
|
|
|
select { |
|
|
|
|
case event := <-a.events: |
|
|
|
|
if event == nil { |
|
|
|
|
break EventLoop |
|
|
|
|
} |
|
|
|
|
handle(event) |
|
|
|
|
continue |
|
|
|
|
default: |
|
|
|
|
a.Lock() |
|
|
|
|
screen := a.screen |
|
|
|
|
a.Unlock() |
|
|
|
|
|
|
|
|
|
if screen == nil { |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
select { |
|
|
|
|
case event := <-a.events: |
|
|
|
|
if event == nil { |
|
|
|
|
break EventLoop |
|
|
|
|
} |
|
|
|
|
handle(event) |
|
|
|
|
case update := <-a.updates: |
|
|
|
|
update() |
|
|
|
|
// Wait for next event.
|
|
|
|
|
event := screen.PollEvent() |
|
|
|
|
if event == nil { |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
semaphore.Lock() |
|
|
|
|
handle(event) |
|
|
|
|
semaphore.Unlock() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Wait for the event loop to finish.
|
|
|
|
|
// Wait for the screen replacement event loop to finish.
|
|
|
|
|
wg.Wait() |
|
|
|
|
a.screen = nil |
|
|
|
|
|
|
|
|
@ -590,13 +588,12 @@ func (a *Application) Stop() {
|
|
|
|
|
// terminal UI mode was not exited, and "f" was not called.
|
|
|
|
|
func (a *Application) Suspend(f func()) bool { |
|
|
|
|
a.Lock() |
|
|
|
|
defer a.Unlock() |
|
|
|
|
|
|
|
|
|
if a.screen == nil { |
|
|
|
|
a.Unlock() |
|
|
|
|
return false // Screen has not yet been initialized.
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err := a.screen.Suspend() |
|
|
|
|
a.Unlock() |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
@ -604,7 +601,9 @@ func (a *Application) Suspend(f func()) bool {
|
|
|
|
|
// Wait for "f" to return.
|
|
|
|
|
f() |
|
|
|
|
|
|
|
|
|
a.Lock() |
|
|
|
|
err = a.screen.Resume() |
|
|
|
|
a.Unlock() |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|