Skip to content

Commit db9e258

Browse files
author
Joel Schutz
committed
Reimplements director with simplified interface
1 parent 7921b5b commit db9e258

File tree

5 files changed

+94
-84
lines changed

5 files changed

+94
-84
lines changed

director.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ type SceneTransitionTrigger int
44

55
// A Directive is a struct that represents how a scene should be transitioned
66
type Directive[T any] struct {
7-
Dest Scene[T, *SceneDirector[T]]
8-
Transition SceneTransition[T, *SceneDirector[T]]
7+
Dest Scene[T]
8+
Transition SceneTransition[T]
99
Trigger SceneTransitionTrigger
1010
}
1111

1212
// A SceneDirector is a struct that manages the transitions between scenes
1313
type SceneDirector[T any] struct {
1414
SceneManager[T]
15-
RuleSet map[Scene[T, *SceneDirector[T]]][]Directive[T]
15+
RuleSet map[Scene[T]][]Directive[T]
1616
}
1717

18-
func NewSceneDirector[T any](scene Scene[T, *SceneDirector[T]], state T, RuleSet map[Scene[T, *SceneDirector[T]]][]Directive[T]) *SceneDirector[T] {
18+
func NewSceneDirector[T any](scene Scene[T], state T, RuleSet map[Scene[T]][]Directive[T]) *SceneDirector[T] {
1919
s := &SceneDirector[T]{RuleSet: RuleSet}
2020
s.current = scene
2121
scene.Load(state, s)
@@ -24,14 +24,14 @@ func NewSceneDirector[T any](scene Scene[T, *SceneDirector[T]], state T, RuleSet
2424

2525
// ProcessTrigger finds if a transition should be triggered
2626
func (d *SceneDirector[T]) ProcessTrigger(trigger SceneTransitionTrigger) {
27-
for _, directive := range d.RuleSet[d.current.(Scene[T, *SceneDirector[T]])] {
27+
for _, directive := range d.RuleSet[d.current.(Scene[T])] {
2828
if directive.Trigger == trigger {
2929
if directive.Transition != nil {
3030
// With transition
3131
// Equivalent to SwitchWithTransition
32-
sc := d.current.(Scene[T, *SceneDirector[T]])
33-
directive.Transition.Start(sc, directive.Dest, &d.SceneManager)
34-
if c, ok := sc.(TransitionAwareScene[T, *SceneDirector[T]]); ok {
32+
sc := d.current.(Scene[T])
33+
directive.Transition.Start(sc, directive.Dest, d)
34+
if c, ok := sc.(TransitionAwareScene[T]); ok {
3535
directive.Dest.Load(c.PreTransition(directive.Dest), d)
3636
} else {
3737
directive.Dest.Load(sc.Unload(), d)
@@ -40,7 +40,7 @@ func (d *SceneDirector[T]) ProcessTrigger(trigger SceneTransitionTrigger) {
4040
} else {
4141
// No transition
4242
// Equivalent to SwitchTo
43-
if c, ok := d.current.(Scene[T, *SceneDirector[T]]); ok {
43+
if c, ok := d.current.(Scene[T]); ok {
4444
directive.Dest.Load(c.Unload(), d)
4545
d.current = directive.Dest
4646
}
@@ -49,3 +49,12 @@ func (d *SceneDirector[T]) ProcessTrigger(trigger SceneTransitionTrigger) {
4949
}
5050
}
5151
}
52+
53+
func (d *SceneDirector[T]) ReturnFromTransition(scene, orgin Scene[T]) {
54+
if c, ok := scene.(TransitionAwareScene[T]); ok {
55+
c.PostTransition(orgin.Unload(), orgin)
56+
} else {
57+
scene.Load(orgin.Unload(), d)
58+
}
59+
d.current = scene
60+
}

helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func MaxInt(a, b int) int {
3333
}
3434

3535
// Pre-draw scenes
36-
func PreDraw[T any, M SceneController[T]](bounds image.Rectangle, fromScene, toScene Scene[T, M]) (*ebiten.Image, *ebiten.Image) {
36+
func PreDraw[T any](bounds image.Rectangle, fromScene, toScene Scene[T]) (*ebiten.Image, *ebiten.Image) {
3737
fromImg := ebiten.NewImage(bounds.Dx(), bounds.Dy())
3838
fromScene.Draw(fromImg)
3939

manager.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,40 @@ type SceneManager[T any] struct {
66
current ProtoScene[T]
77
}
88

9-
func NewSceneManager[T any](scene Scene[T, *SceneManager[T]], state T) *SceneManager[T] {
9+
func NewSceneManager[T any](scene Scene[T], state T) *SceneManager[T] {
1010
s := &SceneManager[T]{current: scene}
1111
scene.Load(state, s)
1212
return s
1313
}
1414

1515
// Scene Switching
16-
func (s *SceneManager[T]) SwitchTo(scene Scene[T, *SceneManager[T]]) {
17-
if c, ok := s.current.(Scene[T, *SceneManager[T]]); ok {
16+
func (s *SceneManager[T]) SwitchTo(scene Scene[T]) {
17+
if c, ok := s.current.(Scene[T]); ok {
1818
scene.Load(c.Unload(), s)
1919
s.current = scene
2020
}
2121
}
2222

23+
func (s *SceneManager[T]) SwitchWithTransition(scene Scene[T], transition SceneTransition[T]) {
24+
sc := s.current.(Scene[T])
25+
transition.Start(sc, scene, s)
26+
if c, ok := sc.(TransitionAwareScene[T]); ok {
27+
scene.Load(c.PreTransition(scene), s)
28+
} else {
29+
scene.Load(sc.Unload(), s)
30+
}
31+
s.current = transition
32+
}
33+
34+
func (s *SceneManager[T]) ReturnFromTransition(scene, orgin Scene[T]) {
35+
if c, ok := scene.(TransitionAwareScene[T]); ok {
36+
c.PostTransition(orgin.Unload(), orgin)
37+
} else {
38+
scene.Load(orgin.Unload(), s)
39+
}
40+
s.current = scene
41+
}
42+
2343
// Ebiten Interface
2444
func (s *SceneManager[T]) Update() error {
2545
return s.current.Update()

scene.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ type ProtoScene[T any] interface {
99
}
1010

1111
type SceneController[T any] interface {
12-
*SceneManager[T] | *SceneDirector[T]
12+
// *SceneManager[T] | *SceneDirector[T]
13+
ReturnFromTransition(scene, orgin Scene[T])
1314
}
1415

15-
type Scene[T any, M SceneController[T]] interface {
16+
type Scene[T any] interface {
1617
ProtoScene[T]
17-
Load(T, M) // Runs when scene is first started, must keep state and SceneManager
18-
Unload() T // Runs when scene is discarted, must return last state
18+
Load(T, SceneController[T]) // Runs when scene is first started, must keep state and SceneManager
19+
Unload() T // Runs when scene is discarted, must return last state
1920
}
2021

21-
type TransitionAwareScene[T any, M SceneController[T]] interface {
22-
Scene[T, M]
23-
PreTransition(Scene[T, M]) T // Runs before new scene is loaded, must return last state
24-
PostTransition(T, Scene[T, M]) // Runs when old scene is unloaded
22+
type TransitionAwareScene[T any] interface {
23+
Scene[T]
24+
PreTransition(Scene[T]) T // Runs before new scene is loaded, must return last state
25+
PostTransition(T, Scene[T]) // Runs when old scene is unloaded
2526
}

transition.go

Lines changed: 43 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,26 @@ import (
66
"github.com/hajimehoshi/ebiten/v2"
77
)
88

9-
type SceneTransition[T any, M SceneController[T]] interface {
9+
type SceneTransition[T any] interface {
1010
ProtoScene[T]
11-
Start(fromScene, toScene Scene[T, M], sm *SceneManager[T])
11+
Start(fromScene, toScene Scene[T], sm SceneController[T])
1212
End()
1313
}
1414

15-
type BaseTransition[T any, M SceneController[T]] struct {
16-
fromScene Scene[T, M]
17-
toScene Scene[T, M]
18-
sm *SceneManager[T]
15+
type BaseTransition[T any] struct {
16+
fromScene Scene[T]
17+
toScene Scene[T]
18+
sm SceneController[T]
1919
}
2020

21-
func (t *BaseTransition[T, M]) Start(fromScene, toScene Scene[T, M], sm *SceneManager[T]) {
21+
func (t *BaseTransition[T]) Start(fromScene, toScene Scene[T], sm SceneController[T]) {
2222
t.fromScene = fromScene
2323
t.toScene = toScene
2424
t.sm = sm
2525
}
2626

2727
// Update updates the transition state
28-
func (t *BaseTransition[T, M]) Update() error {
28+
func (t *BaseTransition[T]) Update() error {
2929
// Update the scenes
3030
err := t.fromScene.Update()
3131
if err != nil {
@@ -41,61 +41,41 @@ func (t *BaseTransition[T, M]) Update() error {
4141
}
4242

4343
// Layout updates the layout of the scenes
44-
func (t *BaseTransition[T, M]) Layout(outsideWidth, outsideHeight int) (int, int) {
44+
func (t *BaseTransition[T]) Layout(outsideWidth, outsideHeight int) (int, int) {
4545
sw, sh := t.fromScene.Layout(outsideWidth, outsideHeight)
4646
tw, th := t.toScene.Layout(outsideWidth, outsideHeight)
4747

4848
return MaxInt(sw, tw), MaxInt(sh, th)
4949
}
5050

51-
func (s *SceneManager[T]) ReturnFromTransition(scene, orgin Scene[T, *SceneManager[T]]) {
52-
if c, ok := scene.(TransitionAwareScene[T, *SceneManager[T]]); ok {
53-
c.PostTransition(orgin.Unload(), orgin)
54-
} else {
55-
scene.Load(orgin.Unload(), s)
56-
}
57-
s.current = scene
58-
}
59-
60-
func (s *SceneManager[T]) SwitchWithTransition(scene Scene[T, *SceneManager[T]], transition SceneTransition[T, *SceneManager[T]]) {
61-
sc := s.current.(Scene[T, *SceneManager[T]])
62-
transition.Start(sc, scene, s)
63-
if c, ok := sc.(TransitionAwareScene[T, *SceneManager[T]]); ok {
64-
scene.Load(c.PreTransition(scene), s)
65-
} else {
66-
scene.Load(sc.Unload(), s)
67-
}
68-
s.current = transition
69-
}
70-
7151
// Ends transition to the next scene
72-
func (t *BaseTransition[T, M]) End() {
73-
t.sm.ReturnFromTransition(t.toScene.(Scene[T, *SceneManager[T]]), t.fromScene.(Scene[T, *SceneManager[T]]))
52+
func (t *BaseTransition[T]) End() {
53+
t.sm.ReturnFromTransition(t.toScene.(Scene[T]), t.fromScene.(Scene[T]))
7454
}
7555

76-
type FadeTransition[T any, M SceneController[T]] struct {
77-
BaseTransition[T, M]
56+
type FadeTransition[T any] struct {
57+
BaseTransition[T]
7858
factor float32 // factor used for the fade-in/fade-out effect
7959
alpha float32 // alpha value used for the fade-in/fade-out effect
8060
isFadingIn bool // whether the transition is currently fading in or out
8161
frameUpdated bool
8262
}
8363

84-
func NewFadeTransition[T any, M SceneController[T]](factor float32) *FadeTransition[T, M] {
85-
return &FadeTransition[T, M]{
64+
func NewFadeTransition[T any](factor float32) *FadeTransition[T] {
65+
return &FadeTransition[T]{
8666
factor: factor,
8767
}
8868
}
8969

9070
// Start starts the transition from the given "from" scene to the given "to" scene
91-
func (t *FadeTransition[T, M]) Start(fromScene, toScene Scene[T, M], sm *SceneManager[T]) {
71+
func (t *FadeTransition[T]) Start(fromScene, toScene Scene[T], sm SceneController[T]) {
9272
t.BaseTransition.Start(fromScene, toScene, sm)
9373
t.alpha = 0
9474
t.isFadingIn = true
9575
}
9676

9777
// Update updates the transition state
98-
func (t *FadeTransition[T, M]) Update() error {
78+
func (t *FadeTransition[T]) Update() error {
9979
if !t.frameUpdated {
10080
// Update the alpha value based on the current state of the transition
10181
if t.isFadingIn {
@@ -119,7 +99,7 @@ func (t *FadeTransition[T, M]) Update() error {
11999
}
120100

121101
// Draw draws the transition effect
122-
func (t *FadeTransition[T, M]) Draw(screen *ebiten.Image) {
102+
func (t *FadeTransition[T]) Draw(screen *ebiten.Image) {
123103
toImg, fromImg := PreDraw(screen.Bounds(), t.fromScene, t.toScene)
124104
toOp, fromOp := &ebiten.DrawImageOptions{}, &ebiten.DrawImageOptions{}
125105

@@ -140,8 +120,8 @@ func (t *FadeTransition[T, M]) Draw(screen *ebiten.Image) {
140120
t.frameUpdated = false
141121
}
142122

143-
type SlideTransition[T any, M SceneController[T]] struct {
144-
BaseTransition[T, M]
123+
type SlideTransition[T any] struct {
124+
BaseTransition[T]
145125
factor float64 // factor used for the slide-in/slide-out effect
146126
direction SlideDirection
147127
offset float64
@@ -157,21 +137,21 @@ const (
157137
BottomToTop
158138
)
159139

160-
func NewSlideTransition[T any, M SceneController[T]](direction SlideDirection, factor float64) *SlideTransition[T, M] {
161-
return &SlideTransition[T, M]{
140+
func NewSlideTransition[T any](direction SlideDirection, factor float64) *SlideTransition[T] {
141+
return &SlideTransition[T]{
162142
direction: direction,
163143
factor: factor,
164144
}
165145
}
166146

167147
// Start starts the transition from the given "from" scene to the given "to" scene
168-
func (t *SlideTransition[T, M]) Start(fromScene Scene[T, M], toScene Scene[T, M], sm *SceneManager[T]) {
148+
func (t *SlideTransition[T]) Start(fromScene Scene[T], toScene Scene[T], sm SceneController[T]) {
169149
t.BaseTransition.Start(fromScene, toScene, sm)
170150
t.offset = 0
171151
}
172152

173153
// Update updates the transition state
174-
func (t *SlideTransition[T, M]) Update() error {
154+
func (t *SlideTransition[T]) Update() error {
175155
if !t.frameUpdated {
176156
// Update the offset value based on the current state of the transition
177157
if t.offset >= 1.0 {
@@ -188,7 +168,7 @@ func (t *SlideTransition[T, M]) Update() error {
188168
}
189169

190170
// Draw draws the transition effect
191-
func (t *SlideTransition[T, M]) Draw(screen *ebiten.Image) {
171+
func (t *SlideTransition[T]) Draw(screen *ebiten.Image) {
192172
toImg, fromImg := PreDraw(screen.Bounds(), t.fromScene, t.toScene)
193173
toOp, fromOp := &ebiten.DrawImageOptions{}, &ebiten.DrawImageOptions{}
194174

@@ -221,29 +201,29 @@ func (t *SlideTransition[T, M]) Draw(screen *ebiten.Image) {
221201

222202
// Timed Variants of the transition
223203

224-
func NewTicksTimedFadeTransition[T any, M SceneController[T]](duration time.Duration) *FadeTransition[T, M] {
225-
return NewFadeTransition[T, M](float32(DurationToFactor(float64(ebiten.TPS()), duration)))
204+
func NewTicksTimedFadeTransition[T any](duration time.Duration) *FadeTransition[T] {
205+
return NewFadeTransition[T](float32(DurationToFactor(float64(ebiten.TPS()), duration)))
226206
}
227207

228-
type TimedFadeTransition[T any, M SceneController[T]] struct {
229-
FadeTransition[T, M]
208+
type TimedFadeTransition[T any] struct {
209+
FadeTransition[T]
230210
initialTime time.Time
231211
duration time.Duration
232212
}
233213

234-
func NewDurationTimedFadeTransition[T any, M SceneController[T]](duration time.Duration) *TimedFadeTransition[T, M] {
235-
return &TimedFadeTransition[T, M]{
214+
func NewDurationTimedFadeTransition[T any](duration time.Duration) *TimedFadeTransition[T] {
215+
return &TimedFadeTransition[T]{
236216
duration: duration,
237-
FadeTransition: *NewFadeTransition[T, M](0.),
217+
FadeTransition: *NewFadeTransition[T](0.),
238218
}
239219
}
240220

241-
func (t *TimedFadeTransition[T, M]) Start(fromScene, toScene Scene[T, M], sm *SceneManager[T]) {
221+
func (t *TimedFadeTransition[T]) Start(fromScene, toScene Scene[T], sm SceneController[T]) {
242222
t.FadeTransition.Start(fromScene, toScene, sm)
243223
t.initialTime = Clock.Now()
244224
}
245225

246-
func (t *TimedFadeTransition[T, M]) Update() error {
226+
func (t *TimedFadeTransition[T]) Update() error {
247227
if !t.frameUpdated {
248228
// Update the alpha value based on the current state of the transition
249229
if t.isFadingIn {
@@ -267,29 +247,29 @@ func (t *TimedFadeTransition[T, M]) Update() error {
267247

268248
}
269249

270-
func NewTicksTimedSlideTransition[T any, M SceneController[T]](direction SlideDirection, duration time.Duration) *SlideTransition[T, M] {
271-
return NewSlideTransition[T, M](direction, DurationToFactor(float64(ebiten.TPS()), duration))
250+
func NewTicksTimedSlideTransition[T any](direction SlideDirection, duration time.Duration) *SlideTransition[T] {
251+
return NewSlideTransition[T](direction, DurationToFactor(float64(ebiten.TPS()), duration))
272252
}
273253

274-
type TimedSlideTransition[T any, M SceneController[T]] struct {
275-
SlideTransition[T, M]
254+
type TimedSlideTransition[T any] struct {
255+
SlideTransition[T]
276256
initialTime time.Time
277257
duration time.Duration
278258
}
279259

280-
func NewDurationTimedSlideTransition[T any, M SceneController[T]](direction SlideDirection, duration time.Duration) *TimedSlideTransition[T, M] {
281-
return &TimedSlideTransition[T, M]{
260+
func NewDurationTimedSlideTransition[T any](direction SlideDirection, duration time.Duration) *TimedSlideTransition[T] {
261+
return &TimedSlideTransition[T]{
282262
duration: duration,
283-
SlideTransition: *NewSlideTransition[T, M](direction, 0.),
263+
SlideTransition: *NewSlideTransition[T](direction, 0.),
284264
}
285265
}
286266

287-
func (t *TimedSlideTransition[T, M]) Start(fromScene, toScene Scene[T, M], sm *SceneManager[T]) {
267+
func (t *TimedSlideTransition[T]) Start(fromScene, toScene Scene[T], sm SceneController[T]) {
288268
t.SlideTransition.Start(fromScene, toScene, sm)
289269
t.initialTime = Clock.Now()
290270
}
291271

292-
func (t *TimedSlideTransition[T, M]) Update() error {
272+
func (t *TimedSlideTransition[T]) Update() error {
293273
if !t.frameUpdated {
294274
// Update the offset value based on the current state of the transition
295275
if t.offset >= 1.0 {

0 commit comments

Comments
 (0)