/
scene.go
110 lines (93 loc) · 2.41 KB
/
scene.go
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package scenes
import (
"github.com/gabz57/goledmatrix/canvas"
"github.com/gabz57/goledmatrix/canvas/effect"
"github.com/gabz57/goledmatrix/components"
"github.com/gabz57/goledmatrix/controller"
"time"
)
type SceneController interface {
HandleGamepadEvent(event *controller.GamepadEvent, projection *controller.GamepadProjection)
HandleKeyboardEvent(event *controller.KeyboardEvent, projection *controller.KeyboardProjection)
}
type Scene struct {
components []components.Component
duration time.Duration
effects []effect.DynamicEffect
controller SceneController
}
func NewScene(components []components.Component, duration time.Duration) *Scene {
return &Scene{
components: components,
duration: duration,
}
}
func (s *Scene) WithController(controller SceneController) *Scene {
s.controller = controller
return s
}
func (s *Scene) WithEffect(effect effect.DynamicEffect) *Scene {
s.effects = append(s.effects, effect)
return s
}
func (s *Scene) WithEffects(effects []effect.DynamicEffect) *Scene {
for _, dynamicEffect := range effects {
_ = s.WithEffect(dynamicEffect)
}
return s
}
func (s *Scene) GamepadControl(gamepad *controller.Gamepad) {
if s.controller == nil {
return
}
for {
select {
case event := <-(*(*gamepad).EventChannel()):
s.controller.HandleGamepadEvent(event, (*gamepad).Projection())
default:
// avoid blocking select
return
}
}
}
func (s *Scene) KeyboardControl(keyboard *controller.Keyboard) {
if s.controller == nil {
return
}
for {
select {
case event := <-(*(*keyboard).EventChannel()):
s.controller.HandleKeyboardEvent(event, (*keyboard).Projection())
default:
// avoid blocking select
return
}
}
}
func (s *Scene) Update(elapsedBetweenUpdate time.Duration) bool {
dirtyScene := false
for _, dynamicEffect := range s.effects {
dirtyScene = dynamicEffect.Update(elapsedBetweenUpdate) || dirtyScene
}
for _, component := range s.components {
dirtyScene = component.Update(elapsedBetweenUpdate) || dirtyScene
}
return dirtyScene
}
func (s *Scene) Render(canvas canvas.Canvas) error {
canvas.Clear()
canvas = s.wrapWithEffects(canvas)
for _, component := range s.components {
err := component.Draw(canvas)
if err != nil {
return err
}
}
return canvas.Render()
}
func (s *Scene) wrapWithEffects(canvas canvas.Canvas) canvas.Canvas {
for _, e := range s.effects {
canvas = effect.NewAdapter(canvas, e)
}
return canvas
}