sprite.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2014 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 sprite provides a 2D scene graph for rendering and animation.
  5. //
  6. // A tree of nodes is drawn by a rendering Engine, provided by another
  7. // package. The OS-independent Go version based on the image package is:
  8. //
  9. // golang.org/x/mobile/exp/sprite/portable
  10. //
  11. // An Engine draws a screen starting at a root Node. The tree is walked
  12. // depth-first, with affine transformations applied at each level.
  13. //
  14. // Nodes are rendered relative to their parent.
  15. //
  16. // Typical main loop:
  17. //
  18. // for each frame {
  19. // quantize time.Now() to a clock.Time
  20. // process UI events
  21. // modify the scene's nodes and animations (Arranger values)
  22. // e.Render(scene, t, sz)
  23. // }
  24. package sprite // import "golang.org/x/mobile/exp/sprite"
  25. import (
  26. "image"
  27. "image/draw"
  28. "golang.org/x/mobile/event/size"
  29. "golang.org/x/mobile/exp/f32"
  30. "golang.org/x/mobile/exp/sprite/clock"
  31. )
  32. type Arranger interface {
  33. Arrange(e Engine, n *Node, t clock.Time)
  34. }
  35. type Texture interface {
  36. Bounds() (w, h int)
  37. Download(r image.Rectangle, dst draw.Image)
  38. Upload(r image.Rectangle, src image.Image)
  39. Release()
  40. }
  41. type SubTex struct {
  42. T Texture
  43. R image.Rectangle
  44. }
  45. type Engine interface {
  46. Register(n *Node)
  47. Unregister(n *Node)
  48. LoadTexture(a image.Image) (Texture, error)
  49. SetSubTex(n *Node, x SubTex)
  50. SetTransform(n *Node, m f32.Affine) // sets transform relative to parent.
  51. // Render renders the scene arranged at the given time, for the given
  52. // window configuration (dimensions and resolution).
  53. Render(scene *Node, t clock.Time, sz size.Event)
  54. Release()
  55. }
  56. // A Node is a renderable element and forms a tree of Nodes.
  57. type Node struct {
  58. Parent, FirstChild, LastChild, PrevSibling, NextSibling *Node
  59. Arranger Arranger
  60. // EngineFields contains fields that should only be accessed by Engine
  61. // implementations. It is exported because such implementations can be
  62. // in other packages.
  63. EngineFields struct {
  64. // TODO: separate TexDirty and TransformDirty bits?
  65. Dirty bool
  66. Index int32
  67. SubTex SubTex
  68. }
  69. }
  70. // AppendChild adds a node c as a child of n.
  71. //
  72. // It will panic if c already has a parent or siblings.
  73. func (n *Node) AppendChild(c *Node) {
  74. if c.Parent != nil || c.PrevSibling != nil || c.NextSibling != nil {
  75. panic("sprite: AppendChild called for an attached child Node")
  76. }
  77. last := n.LastChild
  78. if last != nil {
  79. last.NextSibling = c
  80. } else {
  81. n.FirstChild = c
  82. }
  83. n.LastChild = c
  84. c.Parent = n
  85. c.PrevSibling = last
  86. }
  87. // RemoveChild removes a node c that is a child of n. Afterwards, c will have
  88. // no parent and no siblings.
  89. //
  90. // It will panic if c's parent is not n.
  91. func (n *Node) RemoveChild(c *Node) {
  92. if c.Parent != n {
  93. panic("sprite: RemoveChild called for a non-child Node")
  94. }
  95. if n.FirstChild == c {
  96. n.FirstChild = c.NextSibling
  97. }
  98. if c.NextSibling != nil {
  99. c.NextSibling.PrevSibling = c.PrevSibling
  100. }
  101. if n.LastChild == c {
  102. n.LastChild = c.PrevSibling
  103. }
  104. if c.PrevSibling != nil {
  105. c.PrevSibling.NextSibling = c.NextSibling
  106. }
  107. c.Parent = nil
  108. c.PrevSibling = nil
  109. c.NextSibling = nil
  110. }