lifecycle.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package lifecycle defines an event for an app's lifecycle.
  5. //
  6. // The app lifecycle consists of moving back and forth between an ordered
  7. // sequence of stages. For example, being at a stage greater than or equal to
  8. // StageVisible means that the app is visible on the screen.
  9. //
  10. // A lifecycle event is a change from one stage to another, which crosses every
  11. // intermediate stage. For example, changing from StageAlive to StageFocused
  12. // implicitly crosses StageVisible.
  13. //
  14. // Crosses can be in a positive or negative direction. A positive crossing of
  15. // StageFocused means that the app has gained the focus. A negative crossing
  16. // means it has lost the focus.
  17. //
  18. // See the golang.org/x/mobile/app package for details on the event model.
  19. package lifecycle // import "golang.org/x/mobile/event/lifecycle"
  20. import (
  21. "fmt"
  22. )
  23. // Cross is whether a lifecycle stage was crossed.
  24. type Cross uint32
  25. func (c Cross) String() string {
  26. switch c {
  27. case CrossOn:
  28. return "on"
  29. case CrossOff:
  30. return "off"
  31. }
  32. return "none"
  33. }
  34. const (
  35. CrossNone Cross = 0
  36. CrossOn Cross = 1
  37. CrossOff Cross = 2
  38. )
  39. // Event is a lifecycle change from an old stage to a new stage.
  40. type Event struct {
  41. From, To Stage
  42. // DrawContext is the state used for painting, if any is valid.
  43. //
  44. // For OpenGL apps, a non-nil DrawContext is a gl.Context.
  45. //
  46. // TODO: make this an App method if we move away from an event channel?
  47. DrawContext interface{}
  48. }
  49. func (e Event) String() string {
  50. return fmt.Sprintf("lifecycle.Event{From:%v, To:%v, DrawContext:%v}", e.From, e.To, e.DrawContext)
  51. }
  52. // Crosses reports whether the transition from From to To crosses the stage s:
  53. // - It returns CrossOn if it does, and the lifecycle change is positive.
  54. // - It returns CrossOff if it does, and the lifecycle change is negative.
  55. // - Otherwise, it returns CrossNone.
  56. //
  57. // See the documentation for Stage for more discussion of positive and negative
  58. // crosses.
  59. func (e Event) Crosses(s Stage) Cross {
  60. switch {
  61. case e.From < s && e.To >= s:
  62. return CrossOn
  63. case e.From >= s && e.To < s:
  64. return CrossOff
  65. }
  66. return CrossNone
  67. }
  68. // Stage is a stage in the app's lifecycle. The values are ordered, so that a
  69. // lifecycle change from stage From to stage To implicitly crosses every stage
  70. // in the range (min, max], exclusive on the low end and inclusive on the high
  71. // end, where min is the minimum of From and To, and max is the maximum.
  72. //
  73. // The documentation for individual stages talk about positive and negative
  74. // crosses. A positive lifecycle change is one where its From stage is less
  75. // than its To stage. Similarly, a negative lifecycle change is one where From
  76. // is greater than To. Thus, a positive lifecycle change crosses every stage in
  77. // the range (From, To] in increasing order, and a negative lifecycle change
  78. // crosses every stage in the range (To, From] in decreasing order.
  79. type Stage uint32
  80. // TODO: how does iOS map to these stages? What do cross-platform mobile
  81. // abstractions do?
  82. const (
  83. // StageDead is the zero stage. No lifecycle change crosses this stage,
  84. // but:
  85. // - A positive change from this stage is the very first lifecycle change.
  86. // - A negative change to this stage is the very last lifecycle change.
  87. StageDead Stage = iota
  88. // StageAlive means that the app is alive.
  89. // - A positive cross means that the app has been created.
  90. // - A negative cross means that the app is being destroyed.
  91. // Each cross, either from or to StageDead, will occur only once.
  92. // On Android, these correspond to onCreate and onDestroy.
  93. StageAlive
  94. // StageVisible means that the app window is visible.
  95. // - A positive cross means that the app window has become visible.
  96. // - A negative cross means that the app window has become invisible.
  97. // On Android, these correspond to onStart and onStop.
  98. // On Desktop, an app window can become invisible if e.g. it is minimized,
  99. // unmapped, or not on a visible workspace.
  100. StageVisible
  101. // StageFocused means that the app window has the focus.
  102. // - A positive cross means that the app window has gained the focus.
  103. // - A negative cross means that the app window has lost the focus.
  104. // On Android, these correspond to onResume and onFreeze.
  105. StageFocused
  106. )
  107. func (s Stage) String() string {
  108. switch s {
  109. case StageDead:
  110. return "StageDead"
  111. case StageAlive:
  112. return "StageAlive"
  113. case StageVisible:
  114. return "StageVisible"
  115. case StageFocused:
  116. return "StageFocused"
  117. default:
  118. return fmt.Sprintf("lifecycle.Stage(%d)", s)
  119. }
  120. }