2021-10-01 15:30:22 +10:00
|
|
|
/*
|
|
|
|
Copyright 2021 Josh Deprez
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2021-09-20 12:18:03 +10:00
|
|
|
package engine
|
|
|
|
|
2021-09-23 16:47:43 +10:00
|
|
|
import (
|
|
|
|
"encoding/gob"
|
|
|
|
|
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
|
|
|
)
|
2021-09-20 12:18:03 +10:00
|
|
|
|
2021-09-21 12:36:49 +10:00
|
|
|
var _ interface {
|
|
|
|
Drawer
|
|
|
|
DrawManager
|
|
|
|
Scanner
|
|
|
|
} = &DrawDFS{}
|
|
|
|
|
2021-09-23 16:47:43 +10:00
|
|
|
func init() {
|
|
|
|
gob.Register(&DrawDFS{})
|
|
|
|
}
|
|
|
|
|
2021-09-24 12:29:55 +10:00
|
|
|
// DrawDFS is a DrawManager that does not add any structure. Components are
|
2021-09-20 12:18:03 +10:00
|
|
|
// drawn in the order in which they are encountered by a depth-first search
|
2021-10-04 15:58:18 +11:00
|
|
|
// through the game tree using Query, without any extra sorting based on Z
|
|
|
|
// values or consideration for DrawOrderer.
|
2021-09-20 12:18:03 +10:00
|
|
|
type DrawDFS struct {
|
2021-09-22 14:37:00 +10:00
|
|
|
Child interface{}
|
2021-09-20 12:18:03 +10:00
|
|
|
Hides
|
2021-09-30 10:39:23 +10:00
|
|
|
|
|
|
|
game *Game
|
2021-09-20 12:18:03 +10:00
|
|
|
}
|
|
|
|
|
2021-10-11 17:33:06 +11:00
|
|
|
// Draw draws all descendant components (that are not managed by some other
|
|
|
|
// DrawManager) in a pre-order traversal.
|
2021-09-21 12:36:49 +10:00
|
|
|
func (d *DrawDFS) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
|
2021-10-04 15:57:31 +11:00
|
|
|
stack := []ebiten.DrawImageOptions{*opts}
|
|
|
|
d.game.Query(d, DrawerType,
|
|
|
|
// visitPre
|
|
|
|
func(x interface{}) error {
|
|
|
|
if h, ok := x.(Hider); ok && h.Hidden() {
|
|
|
|
return Skip
|
|
|
|
}
|
|
|
|
opts := stack[len(stack)-1]
|
|
|
|
if tf, ok := x.(Transformer); ok {
|
|
|
|
opts = concatOpts(tf.Transform(), opts)
|
|
|
|
stack = append(stack, opts)
|
|
|
|
}
|
|
|
|
if x == d { // neither draw nor skip d itself
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if dr, ok := x.(Drawer); ok {
|
|
|
|
dr.Draw(screen, &opts)
|
|
|
|
}
|
|
|
|
if _, isDM := x.(DrawManager); isDM {
|
|
|
|
return Skip
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
// visitPost
|
|
|
|
func(x interface{}) error {
|
|
|
|
if _, ok := x.(Transformer); ok {
|
|
|
|
stack = stack[:len(stack)-1]
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
)
|
2021-09-20 12:18:03 +10:00
|
|
|
}
|
|
|
|
|
2021-09-27 16:57:29 +10:00
|
|
|
// ManagesDrawingSubcomponents is present so DrawDFS is recognised as a
|
|
|
|
// DrawManager.
|
2021-09-21 12:36:49 +10:00
|
|
|
func (DrawDFS) ManagesDrawingSubcomponents() {}
|
|
|
|
|
2021-10-11 17:33:06 +11:00
|
|
|
// Prepare saves a reference to g.
|
2021-09-30 10:39:23 +10:00
|
|
|
func (d *DrawDFS) Prepare(g *Game) error {
|
|
|
|
d.game = g
|
|
|
|
return nil
|
2021-09-20 12:18:03 +10:00
|
|
|
}
|
2021-09-22 14:37:00 +10:00
|
|
|
|
2021-09-22 15:55:38 +10:00
|
|
|
// Scan visits d.Child.
|
2021-09-29 13:50:05 +10:00
|
|
|
func (d *DrawDFS) Scan(visit VisitFunc) error {
|
2021-09-22 15:48:02 +10:00
|
|
|
return visit(d.Child)
|
|
|
|
}
|
2021-09-23 14:17:18 +10:00
|
|
|
|
|
|
|
func (d *DrawDFS) String() string { return "DrawDFS" }
|