Load/Prepare refactor

This commit is contained in:
Josh Deprez 2021-09-22 17:04:27 +10:00
parent 6d0838a369
commit 39ad2e9f8d
3 changed files with 40 additions and 30 deletions

View file

@ -227,6 +227,38 @@ func postorderWalk(component, parent interface{}, visit func(component, parent i
return visit(component, parent)
}
// Load loads a component and all subcomponents recursively.
// Note that this method does not implement Loader.
func (g *Game) Load(component interface{}, assets fs.FS) error {
if l, ok := component.(Loader); ok {
if err := l.Load(assets); err != nil {
return err
}
}
if sc, ok := component.(Scanner); ok {
return sc.Scan(func(x interface{}) error {
return g.Load(x, assets)
})
}
return nil
}
// Prepare prepares a component and all subcomponents recursively.
// Note that this method does not implement Prepper.
func (g *Game) Prepare(component interface{}) error {
// Postorder traversal, in case ancestors depend on descendants being
// ready to answer queries.
if sc, ok := component.(Scanner); ok {
if err := sc.Scan(g.Prepare); err != nil {
return err
}
}
if p, ok := component.(Prepper); ok {
return p.Prepare(g)
}
return nil
}
// LoadAndPrepare first calls Load on all Loaders. Once loading is complete, it
// builds the component databases and then calls Prepare on every Preparer.
// LoadAndPrepare must be called before any calls to Component or Query.
@ -237,12 +269,7 @@ func (g *Game) LoadAndPrepare(assets fs.FS) error {
// Load all the Loaders.
startLoad := time.Now()
if err := PreorderWalk(g, func(c, _ interface{}) error {
if l, ok := c.(Loader); ok {
return l.Load(assets)
}
return nil
}); err != nil {
if err := g.Load(g.Root, assets); err != nil {
return err
}
log.Printf("finished loading in %v", time.Since(startLoad))
@ -261,15 +288,9 @@ func (g *Game) LoadAndPrepare(assets fs.FS) error {
// Prepare all the Preppers
startPrep := time.Now()
if err := PostorderWalk(g, func(c, _ interface{}) error {
if p, ok := c.(Prepper); ok {
return p.Prepare(g)
}
return nil
}); err != nil {
if err := g.Prepare(g.Root); err != nil {
return err
}
log.Printf("finished preparing in %v", time.Since(startPrep))
return nil
}

View file

@ -117,23 +117,12 @@ func (aw *Awakeman) realUpdate() error {
if aw.bubbleTimer <= 0 {
aw.bubbleTimer = bubblePeriod
bubble := NewBubble(aw.Sprite.Actor.Pos.Add(geom.Pt3(-3, -20, -1)))
if err := engine.PreorderWalk(bubble, func(c, _ interface{}) error {
if p, ok := c.(engine.Loader); ok {
return p.Load(Assets)
}
return nil
}); err != nil {
if err := aw.game.Load(bubble, Assets); err != nil {
return err
}
// Add bubble to same parent as aw
par := aw.game.Parent(aw)
aw.game.PathRegister(bubble, par)
if err := engine.PostorderWalk(bubble, func(c, _ interface{}) error {
if p, ok := c.(engine.Prepper); ok {
return p.Prepare(aw.game)
}
return nil
}); err != nil {
aw.game.PathRegister(bubble, aw.game.Parent(aw))
if err := aw.game.Prepare(bubble); err != nil {
return err
}
bubble.Sprite.SetAnim(bubble.Sprite.Sheet.NewAnim("bubble"))

View file

@ -73,16 +73,16 @@ func (b *Bubble) Update() error {
if b.Life <= 0 {
b.game.PathUnregister(b)
}
if false {
if true {
// not using MoveX/MoveY/... because collisions are unnecessary -
// this is an effect particle; if it overlaps a solid, who cares
b.Sprite.Actor.Pos = b.Sprite.Actor.Pos.Add(geom.Pt3(
//lint:ignore SA4000 one random minus another is not always zero...
rand.Intn(3)-1, rand.Intn(2)-1, rand.Intn(2)-rand.Intn(2),
rand.Intn(3)-1, -1, rand.Intn(2)-rand.Intn(2),
))
} else {
b.Sprite.Actor.MoveX(float64(rand.Intn(3)-1), nil)
b.Sprite.Actor.MoveY(float64(rand.Intn(2)-1), nil)
b.Sprite.Actor.MoveY(-1, nil)
//lint:ignore SA4000 one random minus another is not always zero...
b.Sprite.Actor.MoveZ(float64(rand.Intn(2)-rand.Intn(2)), nil)
}