ichigo/engine/drawdfs.go

98 lines
2.3 KiB
Go
Raw Normal View History

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
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.
func (d *DrawDFS) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
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.
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" }