Split Scan and Build
This commit is contained in:
parent
1c8d054aff
commit
3d75693cc2
4 changed files with 29 additions and 13 deletions
|
@ -1,6 +1,7 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -42,11 +43,10 @@ type GobDumper struct {
|
|||
game *Game
|
||||
}
|
||||
|
||||
func (d *GobDumper) Scan(g *Game) []interface{} {
|
||||
d.game = g
|
||||
return nil
|
||||
}
|
||||
// Build simply stores the reference to the Game.
|
||||
func (d *GobDumper) Build(g *Game) { d.game = g }
|
||||
|
||||
// Update waits for the key combo, then dumps the game state into a gzipped gob.
|
||||
func (d *GobDumper) Update() error {
|
||||
for _, key := range d.KeyCombo {
|
||||
if !ebiten.IsKeyPressed(key) {
|
||||
|
@ -56,12 +56,17 @@ func (d *GobDumper) Update() error {
|
|||
if d.game == nil {
|
||||
return errors.New("nil d.game in GobDumper.Update")
|
||||
}
|
||||
f, err := os.Create(time.Now().Format("20060102030405.gob"))
|
||||
f, err := os.Create(time.Now().Format("20060102030405.gob.gz"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
if err := gob.NewEncoder(f).Encode(d.game); err != nil {
|
||||
gz := gzip.NewWriter(f)
|
||||
defer gz.Close()
|
||||
if err := gob.NewEncoder(gz).Encode(d.game); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gz.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return f.Close()
|
||||
|
|
|
@ -16,11 +16,18 @@ type Identifier interface {
|
|||
Ident() string
|
||||
}
|
||||
|
||||
// Scanner components can be scanned. It is called when the game
|
||||
// Builder components can be built. It is called when the game
|
||||
// component database is being constructed. It should store the Game reference
|
||||
// (if needed later on), and return a slice of all subcomponents.
|
||||
// (if needed later on).
|
||||
type Builder interface {
|
||||
Build(game *Game)
|
||||
}
|
||||
|
||||
// Scanner components can be scanned. It is called when the game tree is walked
|
||||
// (such as when the game component database is constructed).
|
||||
// Scan should return a slice containing all subcomponents.
|
||||
type Scanner interface {
|
||||
Scan(game *Game) []interface{}
|
||||
Scan() []interface{}
|
||||
}
|
||||
|
||||
// Game implements the ebiten methods using a collection of components.
|
||||
|
@ -77,7 +84,8 @@ func (g *Game) UnregisterComponent(c interface{}) {
|
|||
// Component returns the component with a given ID, or nil if there is none.
|
||||
func (g *Game) Component(id string) interface{} { return g.componentsByID[id] }
|
||||
|
||||
// Walk calls v with every component, for as long as visit returns true.
|
||||
// Walk calls v with every component reachable via Scan, for as long as visit
|
||||
// returns true.
|
||||
func (g *Game) Walk(v func(interface{}) bool) {
|
||||
g.walk(g.Scene, v)
|
||||
}
|
||||
|
@ -87,7 +95,7 @@ func (g *Game) walk(c interface{}, v func(interface{}) bool) {
|
|||
return
|
||||
}
|
||||
if sc, ok := c.(Scanner); ok {
|
||||
for _, c := range sc.Scan(g) {
|
||||
for _, c := range sc.Scan() {
|
||||
if !v(c) {
|
||||
return
|
||||
}
|
||||
|
@ -100,6 +108,9 @@ func (g *Game) walk(c interface{}, v func(interface{}) bool) {
|
|||
func (g *Game) Build() {
|
||||
g.componentsByID = make(map[string]interface{})
|
||||
g.Walk(func(c interface{}) bool {
|
||||
if b, ok := c.(Builder); ok {
|
||||
b.Build(g)
|
||||
}
|
||||
g.RegisterComponent(c)
|
||||
return true
|
||||
})
|
||||
|
|
|
@ -65,7 +65,7 @@ func (s *Scene) sortByZ() {
|
|||
}
|
||||
|
||||
// Scan returns all subcomponents.
|
||||
func (s *Scene) Scan(g *Game) []interface{} { return s.Components }
|
||||
func (s *Scene) Scan() []interface{} { return s.Components }
|
||||
|
||||
// Update calls Update on all Updater components.
|
||||
func (s *Scene) Update() error {
|
||||
|
|
2
main.go
2
main.go
|
@ -74,7 +74,7 @@ func main() {
|
|||
ScreenHeight: screenHeight,
|
||||
ScreenWidth: screenWidth,
|
||||
Scene: &engine.Scene{
|
||||
ID: "root_scene",
|
||||
ID: "root",
|
||||
Components: []interface{}{
|
||||
&engine.GobDumper{
|
||||
KeyCombo: []ebiten.Key{ebiten.KeyControl, ebiten.KeyD},
|
||||
|
|
Loading…
Reference in a new issue