| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- // 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 sprite provides a 2D scene graph for rendering and animation.
- //
- // A tree of nodes is drawn by a rendering Engine, provided by another
- // package. The OS-independent Go version based on the image package is:
- //
- // golang.org/x/mobile/exp/sprite/portable
- //
- // An Engine draws a screen starting at a root Node. The tree is walked
- // depth-first, with affine transformations applied at each level.
- //
- // Nodes are rendered relative to their parent.
- //
- // Typical main loop:
- //
- // for each frame {
- // quantize time.Now() to a clock.Time
- // process UI events
- // modify the scene's nodes and animations (Arranger values)
- // e.Render(scene, t, sz)
- // }
- package sprite
- import (
- "image"
- "image/draw"
- "golang.org/x/mobile/event/size"
- "golang.org/x/mobile/exp/f32"
- "golang.org/x/mobile/exp/sprite/clock"
- )
- type Arranger interface {
- Arrange(e Engine, n *Node, t clock.Time)
- }
- type Texture interface {
- Bounds() (w, h int)
- Download(r image.Rectangle, dst draw.Image)
- Upload(r image.Rectangle, src image.Image)
- Release()
- }
- type SubTex struct {
- T Texture
- R image.Rectangle
- }
- type Engine interface {
- Register(n *Node)
- Unregister(n *Node)
- LoadTexture(a image.Image) (Texture, error)
- SetSubTex(n *Node, x SubTex)
- SetTransform(n *Node, m f32.Affine) // sets transform relative to parent.
- // Render renders the scene arranged at the given time, for the given
- // window configuration (dimensions and resolution).
- Render(scene *Node, t clock.Time, sz size.Event)
- Release()
- }
- // A Node is a renderable element and forms a tree of Nodes.
- type Node struct {
- Parent, FirstChild, LastChild, PrevSibling, NextSibling *Node
- Arranger Arranger
- // EngineFields contains fields that should only be accessed by Engine
- // implementations. It is exported because such implementations can be
- // in other packages.
- EngineFields struct {
- // TODO: separate TexDirty and TransformDirty bits?
- Dirty bool
- Index int32
- SubTex SubTex
- }
- }
- // AppendChild adds a node c as a child of n.
- //
- // It will panic if c already has a parent or siblings.
- func (n *Node) AppendChild(c *Node) {
- if c.Parent != nil || c.PrevSibling != nil || c.NextSibling != nil {
- panic("sprite: AppendChild called for an attached child Node")
- }
- last := n.LastChild
- if last != nil {
- last.NextSibling = c
- } else {
- n.FirstChild = c
- }
- n.LastChild = c
- c.Parent = n
- c.PrevSibling = last
- }
- // RemoveChild removes a node c that is a child of n. Afterwards, c will have
- // no parent and no siblings.
- //
- // It will panic if c's parent is not n.
- func (n *Node) RemoveChild(c *Node) {
- if c.Parent != n {
- panic("sprite: RemoveChild called for a non-child Node")
- }
- if n.FirstChild == c {
- n.FirstChild = c.NextSibling
- }
- if c.NextSibling != nil {
- c.NextSibling.PrevSibling = c.PrevSibling
- }
- if n.LastChild == c {
- n.LastChild = c.PrevSibling
- }
- if c.PrevSibling != nil {
- c.PrevSibling.NextSibling = c.NextSibling
- }
- c.Parent = nil
- c.PrevSibling = nil
- c.NextSibling = nil
- }
|