136 lines
4.5 KiB
Go
136 lines
4.5 KiB
Go
|
// Copyright 2015 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 lifecycle defines an event for an app's lifecycle.
|
||
|
//
|
||
|
// The app lifecycle consists of moving back and forth between an ordered
|
||
|
// sequence of stages. For example, being at a stage greater than or equal to
|
||
|
// StageVisible means that the app is visible on the screen.
|
||
|
//
|
||
|
// A lifecycle event is a change from one stage to another, which crosses every
|
||
|
// intermediate stage. For example, changing from StageAlive to StageFocused
|
||
|
// implicitly crosses StageVisible.
|
||
|
//
|
||
|
// Crosses can be in a positive or negative direction. A positive crossing of
|
||
|
// StageFocused means that the app has gained the focus. A negative crossing
|
||
|
// means it has lost the focus.
|
||
|
//
|
||
|
// See the golang.org/x/mobile/app package for details on the event model.
|
||
|
package lifecycle // import "golang.org/x/mobile/event/lifecycle"
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
// Cross is whether a lifecycle stage was crossed.
|
||
|
type Cross uint32
|
||
|
|
||
|
func (c Cross) String() string {
|
||
|
switch c {
|
||
|
case CrossOn:
|
||
|
return "on"
|
||
|
case CrossOff:
|
||
|
return "off"
|
||
|
}
|
||
|
return "none"
|
||
|
}
|
||
|
|
||
|
const (
|
||
|
CrossNone Cross = 0
|
||
|
CrossOn Cross = 1
|
||
|
CrossOff Cross = 2
|
||
|
)
|
||
|
|
||
|
// Event is a lifecycle change from an old stage to a new stage.
|
||
|
type Event struct {
|
||
|
From, To Stage
|
||
|
|
||
|
// DrawContext is the state used for painting, if any is valid.
|
||
|
//
|
||
|
// For OpenGL apps, a non-nil DrawContext is a gl.Context.
|
||
|
//
|
||
|
// TODO: make this an App method if we move away from an event channel?
|
||
|
DrawContext interface{}
|
||
|
}
|
||
|
|
||
|
func (e Event) String() string {
|
||
|
return fmt.Sprintf("lifecycle.Event{From:%v, To:%v, DrawContext:%v}", e.From, e.To, e.DrawContext)
|
||
|
}
|
||
|
|
||
|
// Crosses reports whether the transition from From to To crosses the stage s:
|
||
|
// - It returns CrossOn if it does, and the lifecycle change is positive.
|
||
|
// - It returns CrossOff if it does, and the lifecycle change is negative.
|
||
|
// - Otherwise, it returns CrossNone.
|
||
|
// See the documentation for Stage for more discussion of positive and negative
|
||
|
// crosses.
|
||
|
func (e Event) Crosses(s Stage) Cross {
|
||
|
switch {
|
||
|
case e.From < s && e.To >= s:
|
||
|
return CrossOn
|
||
|
case e.From >= s && e.To < s:
|
||
|
return CrossOff
|
||
|
}
|
||
|
return CrossNone
|
||
|
}
|
||
|
|
||
|
// Stage is a stage in the app's lifecycle. The values are ordered, so that a
|
||
|
// lifecycle change from stage From to stage To implicitly crosses every stage
|
||
|
// in the range (min, max], exclusive on the low end and inclusive on the high
|
||
|
// end, where min is the minimum of From and To, and max is the maximum.
|
||
|
//
|
||
|
// The documentation for individual stages talk about positive and negative
|
||
|
// crosses. A positive lifecycle change is one where its From stage is less
|
||
|
// than its To stage. Similarly, a negative lifecycle change is one where From
|
||
|
// is greater than To. Thus, a positive lifecycle change crosses every stage in
|
||
|
// the range (From, To] in increasing order, and a negative lifecycle change
|
||
|
// crosses every stage in the range (To, From] in decreasing order.
|
||
|
type Stage uint32
|
||
|
|
||
|
// TODO: how does iOS map to these stages? What do cross-platform mobile
|
||
|
// abstractions do?
|
||
|
|
||
|
const (
|
||
|
// StageDead is the zero stage. No lifecycle change crosses this stage,
|
||
|
// but:
|
||
|
// - A positive change from this stage is the very first lifecycle change.
|
||
|
// - A negative change to this stage is the very last lifecycle change.
|
||
|
StageDead Stage = iota
|
||
|
|
||
|
// StageAlive means that the app is alive.
|
||
|
// - A positive cross means that the app has been created.
|
||
|
// - A negative cross means that the app is being destroyed.
|
||
|
// Each cross, either from or to StageDead, will occur only once.
|
||
|
// On Android, these correspond to onCreate and onDestroy.
|
||
|
StageAlive
|
||
|
|
||
|
// StageVisible means that the app window is visible.
|
||
|
// - A positive cross means that the app window has become visible.
|
||
|
// - A negative cross means that the app window has become invisible.
|
||
|
// On Android, these correspond to onStart and onStop.
|
||
|
// On Desktop, an app window can become invisible if e.g. it is minimized,
|
||
|
// unmapped, or not on a visible workspace.
|
||
|
StageVisible
|
||
|
|
||
|
// StageFocused means that the app window has the focus.
|
||
|
// - A positive cross means that the app window has gained the focus.
|
||
|
// - A negative cross means that the app window has lost the focus.
|
||
|
// On Android, these correspond to onResume and onFreeze.
|
||
|
StageFocused
|
||
|
)
|
||
|
|
||
|
func (s Stage) String() string {
|
||
|
switch s {
|
||
|
case StageDead:
|
||
|
return "StageDead"
|
||
|
case StageAlive:
|
||
|
return "StageAlive"
|
||
|
case StageVisible:
|
||
|
return "StageVisible"
|
||
|
case StageFocused:
|
||
|
return "StageFocused"
|
||
|
default:
|
||
|
return fmt.Sprintf("lifecycle.Stage(%d)", s)
|
||
|
}
|
||
|
}
|