blob: 04722f7c927c396195f3f20197541294df9393d7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
// Version 2 of unicorn, uses gif.GIF as store of pixels
// & a separate goroutine to render it so it can do
// animated GIFs
package unicorn
import (
"image"
"image/gif"
"time"
)
// Unicorn2 ...
// Interface for interacting with the Unicorn HAT HD
// Implemented by both real & fake unicorns.
type Unicorn2 interface {
// Change the image
GetGif() *gif.GIF
SetGif(*gif.GIF)
// Starts the rendering goroutine
StartRender()
// Must be implemented to actually render the image to device
renderImage(image.Image)
// Required for os to not think we're stuck
MainLoop()
}
// BaseUnicorn2 ...
// Common to both real & fake unicorns!
// timing code for rendering & stopping rendering
type BaseUnicorn2 struct {
g *gif.GIF
}
func (u *BaseUnicorn2) GetGif() *gif.GIF {
return u.g
}
func (u *BaseUnicorn2) SetGif(g *gif.GIF) {
u.g = g
}
// StartRender ...
// Starts rendering the image. If it's an animated image,
// renders animation frames. Return a channel to stop the
// image rendering.
func (u *FakeUnicorn2) StartRender() chan bool {
stopChan := make(chan bool)
go func() {
timer := time.NewTimer(0)
imageIndex := 0
running := true
for running {
select {
case <-stopChan:
timer.Stop()
running = false
case <-timer.C:
gf := u.GetGif()
im := gf.Image[imageIndex]
delay := gf.Delay[imageIndex] //100ths of a second, 10^-2
u.renderImage(im)
timer.Reset(time.Duration(delay * 10000000)) // nanoseconds 10^-9 sec
imageIndex = (imageIndex + 1) % len(gf.Image)
}
}
}()
return stopChan
}
|