From 84f8e5edccf54821b15716147c6e7a168c18d0b5 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Thu, 16 Jul 2015 15:53:00 +1000 Subject: [PATCH] event: move event.Filter to app.Filter. Change-Id: I11044a6e01b53e441c05fc1baec36718e783622f Reviewed-on: https://go-review.googlesource.com/12288 Reviewed-by: David Crawshaw --- app/app.go | 27 ++++++++++++++++--- app/doc.go | 31 ++++++++++++++++------ event/config/config.go | 2 +- event/event.go | 50 ------------------------------------ event/lifecycle/lifecycle.go | 2 +- event/paint/paint.go | 2 +- event/touch/touch.go | 2 +- example/basic/main.go | 5 ++-- exp/gl/glutil/glimage.go | 4 +-- 9 files changed, 54 insertions(+), 71 deletions(-) delete mode 100644 event/event.go diff --git a/app/app.go b/app/app.go index e36066c..63ec9ee 100644 --- a/app/app.go +++ b/app/app.go @@ -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)) diff --git a/app/doc.go b/app/doc.go index 757c8bc..e50ea21 100644 --- a/app/doc.go +++ b/app/doc.go @@ -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" diff --git a/event/config/config.go b/event/config/config.go index c8ba189..a0af299 100644 --- a/event/config/config.go +++ b/event/config/config.go @@ -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 ( diff --git a/event/event.go b/event/event.go deleted file mode 100644 index b2f7fce..0000000 --- a/event/event.go +++ /dev/null @@ -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) -} diff --git a/event/lifecycle/lifecycle.go b/event/lifecycle/lifecycle.go index c5a9065..9376fe5 100644 --- a/event/lifecycle/lifecycle.go +++ b/event/lifecycle/lifecycle.go @@ -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 ( diff --git a/event/paint/paint.go b/event/paint/paint.go index 3c4d8a2..e659c59 100644 --- a/event/paint/paint.go +++ b/event/paint/paint.go @@ -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 diff --git a/event/touch/touch.go b/event/touch/touch.go index d7f79e6..537a213 100644 --- a/event/touch/touch.go +++ b/event/touch/touch.go @@ -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 diff --git a/example/basic/main.go b/example/basic/main.go index c7d0e4f..32012c2 100644 --- a/example/basic/main.go +++ b/example/basic/main.go @@ -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() { diff --git a/exp/gl/glutil/glimage.go b/exp/gl/glutil/glimage.go index cfc6f99..3d00f29 100644 --- a/exp/gl/glutil/glimage.go +++ b/exp/gl/glutil/glimage.go @@ -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: