mobile/app/app.go

188 lines
4.9 KiB
Go
Raw Normal View History

// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux darwin
package app
import (
"golang.org/x/mobile/event/config"
"golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/gl"
_ "golang.org/x/mobile/internal/mobileinit"
)
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
// Main is called by the main.main function to run the mobile application.
//
// It calls f on the App, in a separate goroutine, as some OS-specific
// libraries require being on 'the main thread'.
func Main(f func(App)) {
main(f)
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
}
// App is how a GUI mobile application interacts with the OS.
type App interface {
// Events returns the events channel. It carries events from the system to
// the app. The type of such events include:
// - config.Event
// - lifecycle.Event
// - paint.Event
// - touch.Event
// from the golang.org/x/mobile/event/etc packages. Other packages may
// define other event types that are carried on this channel.
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
Events() <-chan interface{}
// Send sends an event on the events channel. It does not block.
Send(event interface{})
// EndPaint flushes any pending OpenGL commands or buffers to the screen.
EndPaint()
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
}
var (
lifecycleStage = lifecycle.StageDead
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
pixelsPerPt = float32(1)
eventsOut = make(chan interface{})
eventsIn = pump(eventsOut)
endPaint = make(chan struct{}, 1)
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
)
func sendLifecycle(to lifecycle.Stage) {
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
if lifecycleStage == to {
return
}
eventsIn <- lifecycle.Event{
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
From: lifecycleStage,
To: to,
}
lifecycleStage = to
}
type app struct{}
func (app) Events() <-chan interface{} {
return eventsOut
}
func (app) Send(event interface{}) {
eventsIn <- event
}
func (app) EndPaint() {
// gl.Flush is a lightweight (on modern GL drivers) blocking call
// that ensures all GL functions pending in the gl package have
// been passed onto the GL driver before the app package attempts
// to swap the screen buffer.
//
// This enforces that the final receive (for this paint cycle) on
// gl.WorkAvailable happens before the send on endPaint.
gl.Flush()
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
select {
case endPaint <- struct{}{}:
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
default:
}
}
var filters []func(interface{}) interface{}
// Filter calls each registered event filter function in sequence.
func Filter(event interface{}) interface{} {
for _, f := range filters {
event = f(event)
}
return event
}
// RegisterFilter registers a event filter function to be called by Filter. The
// function can return a different event, or return nil to consume the event,
// but the function can also return its argument unchanged, where its purpose
// is to trigger a side effect rather than modify the event.
//
// RegisterFilter should only be called from init functions.
func RegisterFilter(f func(interface{}) interface{}) {
filters = append(filters, f)
}
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
type stopPumping struct{}
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
// pump returns a channel src such that sending on src will eventually send on
// dst, in order, but that src will always be ready to send/receive soon, even
// if dst currently isn't. It is effectively an infinitely buffered channel.
//
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
// In particular, goroutine A sending on src will not deadlock even if goroutine
// B that's responsible for receiving on dst is currently blocked trying to
// send to A on a separate channel.
//
app: use one thread for both GL and other UI C code. This change will break Darwin. I have only built and tested this on desktop linux and Android linux. A follow-up CL will fix Darwin. Currently, OpenGL gets its own thread, and UI C code (e.g. the Android event loop, or the X11 event loop) gets its own thread. This relies on multiple system-provided UI-related C libraries working nicely together, even when running on different threads. Keeping all the C code on the one thread seems more sound. As side-effects: - In package app/debug, DrawFPS now takes an explicit Config. - In package app, some callbacks now take an explicit Config. - In package exp/sprite, Render now takes an explicit Config. - In package event, there are new events (Config, Draw, Lifecycle), and an event filter mechanism to replace multiple app Callbacks. - In package geom, the deprecated Width, Height and PixelsPerPt global variables were removed in favor of an event.Config that is explicitly passed around (and does not require mutex-locking). Converting a geom.Pt to pixels now requires passing a pixelsPerPt. - In package gl, the Do, Start and Stop functions are removed, as well as the need to call Start in its own goroutine. There is no longer a separate GL thread. Instead, package app explicitly performs any GL work (gl.DoWork) when some is available (gl.WorkAvailable). - In package gl/glutil, Image.Draw now takes an explicit Config. Callbacks are no longer executed on 'the UI thread'. Changing the app programming model from callbacks to events (since a channel of events works with select) will be a follow-up change. Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1 Reviewed-on: https://go-review.googlesource.com/11351 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-23 06:41:48 +00:00
// Send a stopPumping on the src channel to close the dst channel after all queued
// events are sent on dst. After that, other goroutines can still send to src,
// so that such sends won't block forever, but such events will be ignored.
func pump(dst chan interface{}) (src chan interface{}) {
src = make(chan interface{})
go func() {
// initialSize is the initial size of the circular buffer. It must be a
// power of 2.
const initialSize = 16
i, j, buf, mask := 0, 0, make([]interface{}, initialSize), initialSize-1
maybeSrc := src
for {
maybeDst := dst
if i == j {
maybeDst = nil
}
if maybeDst == nil && maybeSrc == nil {
break
}
select {
case maybeDst <- buf[i&mask]:
buf[i&mask] = nil
i++
case e := <-maybeSrc:
if _, ok := e.(stopPumping); ok {
maybeSrc = nil
continue
}
// Allocate a bigger buffer if necessary.
if i+len(buf) == j {
b := make([]interface{}, 2*len(buf))
n := copy(b, buf[j&mask:])
copy(b[n:], buf[:j&mask])
i, j = 0, len(buf)
buf, mask = b, len(b)-1
}
buf[j&mask] = e
j++
}
}
close(dst)
// Block forever.
for range src {
}
}()
return src
}
// TODO: do this for all build targets, not just linux (x11 and Android)? If
// so, should package gl instead of this package call RegisterFilter??
//
// TODO: does Android need this?? It seems to work without it (Nexus 7,
// KitKat). If only x11 needs this, should we move this to x11.go??
func registerGLViewportFilter() {
RegisterFilter(func(e interface{}) interface{} {
if e, ok := e.(config.Event); ok {
w := int(e.PixelsPerPt * float32(e.Width))
h := int(e.PixelsPerPt * float32(e.Height))
gl.Viewport(0, 0, w, h)
}
return e
})
}