2
0
mirror of synced 2025-02-22 06:28:04 +00:00

event: move event.Filter to app.Filter.

Change-Id: I11044a6e01b53e441c05fc1baec36718e783622f
Reviewed-on: https://go-review.googlesource.com/12288
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Nigel Tao 2015-07-16 15:53:00 +10:00
parent 136fa9bbbb
commit 84f8e5edcc
9 changed files with 54 additions and 71 deletions

View File

@ -7,7 +7,6 @@
package app
import (
"golang.org/x/mobile/event"
"golang.org/x/mobile/event/config"
"golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/event/paint"
@ -89,6 +88,26 @@ func (app) EndPaint() {
}
}
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)
}
type stopPumping struct{}
// pump returns a channel src such that sending on src will eventually send on
@ -163,7 +182,7 @@ func Run(cb Callbacks) {
Main(func(a App) {
var c config.Event
for e := range a.Events() {
switch e := event.Filter(e).(type) {
switch e := Filter(e).(type) {
case lifecycle.Event:
switch e.Crosses(lifecycle.StageVisible) {
case lifecycle.CrossOn:
@ -245,12 +264,12 @@ type Callbacks struct {
}
// TODO: do this for all build targets, not just linux (x11 and Android)? If
// so, should package gl instead of this package call event.RegisterFilter??
// 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() {
event.RegisterFilter(func(e interface{}) interface{} {
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))

View File

@ -29,12 +29,15 @@ https://golang.org/x/mobile/cmd/gomobile.
Event processing in Native Apps
The Go runtime is initialized on Android when NativeActivity
onCreate is called, and on iOS when the process starts. In both
cases, Go init functions run before the app lifecycle has started.
The Go runtime is initialized on Android when NativeActivity onCreate is
called, and on iOS when the process starts. In both cases, Go init functions
run before the app lifecycle has started.
An app is expected to call the Main function in main.main. When the
function exits, the app exits.
An app is expected to call the Main function in main.main. When the function
exits, the app exits. Inside the func passed to Main, call Filter on every
event received, and then switch on its type. Registered filters run when the
event is received, not when it is sent, so that filters run in the same
goroutine as other code that calls OpenGL.
package main
@ -42,7 +45,6 @@ function exits, the app exits.
"log"
"golang.org/x/mobile/app"
"golang.org/x/mobile/event"
"golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/event/paint"
)
@ -50,7 +52,7 @@ function exits, the app exits.
func main() {
app.Main(func(a app.App) {
for e := range a.Events() {
switch e := event.Filter(e).(type) {
switch e := app.Filter(e).(type) {
case lifecycle.Event:
// ...
case paint.Event:
@ -61,6 +63,19 @@ function exits, the app exits.
})
}
For details on the event model, see https://golang.org/x/mobile/event.
An event is represented by the empty interface type interface{}. Any value can
be an event. Commonly used types include Event types defined by the following
packages:
- golang.org/x/mobile/event/config
- golang.org/x/mobile/event/lifecycle
- golang.org/x/mobile/event/paint
- golang.org/x/mobile/event/touch
For example, touch.Event is the type that represents touch events. Other
packages may define their own events, and send them on an app's event channel.
Other packages can also register event filters, e.g. to manage resources in
response to lifecycle events. Such packages should call:
app.RegisterFilter(etc)
in an init function inside that package.
*/
package app // import "golang.org/x/mobile/app"

View File

@ -5,7 +5,7 @@
// Package config defines an event for the dimensions and physical resolution
// of the app's window.
//
// See the golang.org/x/mobile/event package for details on the event model.
// See the golang.org/x/mobile/app package for details on the event model.
package config // import "golang.org/x/mobile/event/config"
import (

View File

@ -1,50 +0,0 @@
// 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.
// Package event defines a model for mobile app events, such as user input
// events.
//
// An event is represented by the empty interface type interface{}. Any value
// can be an event. Packages under this directory define a number of commonly
// used events used by the golang.org/x/mobile/app package:
// - golang.org/x/mobile/event/config.Event
// - golang.org/x/mobile/event/lifecycle.Event
// - golang.org/x/mobile/event/paint.Event
// - golang.org/x/mobile/event/touch.Event
// Other packages may define their own events, and post them onto an app's
// event channel.
//
// Other packages can also register event filters, e.g. to manage resources in
// response to lifecycle events. Such packages should call:
// event.RegisterFilter(etc)
// in an init function inside that package.
//
// The program code that consumes an app's events is expected to call
// event.Filter on every event they receive, and then switch on its type:
// for e := range a.Events() {
// switch e := event.Filter(e).(type) {
// etc
// }
// }
package event // import "golang.org/x/mobile/event"
var filters []func(interface{}) interface{}
// Filter calls each registered filter function in sequence.
func Filter(event interface{}) interface{} {
for _, f := range filters {
event = f(event)
}
return event
}
// RegisterFilter registers a 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)
}

View File

@ -16,7 +16,7 @@
// StageFocused means that the app has gained the focus. A negative crossing
// means it has lost the focus.
//
// See the golang.org/x/mobile/event package for details on the event model.
// See the golang.org/x/mobile/app package for details on the event model.
package lifecycle // import "golang.org/x/mobile/event/lifecycle"
import (

View File

@ -4,7 +4,7 @@
// Package paint defines an event for the app being ready to paint.
//
// See the golang.org/x/mobile/event package for details on the event model.
// See the golang.org/x/mobile/app package for details on the event model.
package paint // import "golang.org/x/mobile/event/paint"
// Event indicates that the app is ready to paint the next frame of the GUI. A

View File

@ -4,7 +4,7 @@
// Package touch defines an event for touch input.
//
// See the golang.org/x/mobile/event package for details on the event model.
// See the golang.org/x/mobile/app package for details on the event model.
package touch // import "golang.org/x/mobile/event/touch"
// The best source on android input events is the NDK: include/android/input.h

View File

@ -31,7 +31,6 @@ import (
"log"
"golang.org/x/mobile/app"
"golang.org/x/mobile/event"
"golang.org/x/mobile/event/config"
"golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/event/paint"
@ -58,7 +57,7 @@ func main() {
app.Main(func(a app.App) {
var c config.Event
for e := range a.Events() {
switch e := event.Filter(e).(type) {
switch e := app.Filter(e).(type) {
case lifecycle.Event:
switch e.Crosses(lifecycle.StageVisible) {
case lifecycle.CrossOn:
@ -96,7 +95,7 @@ func onStart() {
offset = gl.GetUniformLocation(program, "offset")
// TODO(crawshaw): the debug package needs to put GL state init here
// Can this be an event.Register call now??
// Can this be an app.RegisterFilter call now??
}
func onStop() {

View File

@ -13,7 +13,7 @@ import (
"runtime"
"sync"
"golang.org/x/mobile/event"
"golang.org/x/mobile/app"
"golang.org/x/mobile/event/config"
"golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/exp/f32"
@ -33,7 +33,7 @@ var glimage struct {
}
func init() {
event.RegisterFilter(func(e interface{}) interface{} {
app.RegisterFilter(func(e interface{}) interface{} {
if e, ok := e.(lifecycle.Event); ok {
switch e.Crosses(lifecycle.StageVisible) {
case lifecycle.CrossOn: