progress
This commit is contained in:
parent
787a05e493
commit
9a9dcd0d40
4 changed files with 42 additions and 10 deletions
|
@ -56,7 +56,7 @@ func (d *DrawDAG) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
|
||||||
}
|
}
|
||||||
// Draw everything in d.dag, where not hidden (itself or any parent)
|
// Draw everything in d.dag, where not hidden (itself or any parent)
|
||||||
// TODO: handle descendant DrawLayers
|
// TODO: handle descendant DrawLayers
|
||||||
d.dag.topIterate(func(x Drawer) {
|
d.dag.topWalk(func(x Drawer) {
|
||||||
// Is d hidden itself?
|
// Is d hidden itself?
|
||||||
if h, ok := x.(Hider); ok && h.Hidden() {
|
if h, ok := x.(Hider); ok && h.Hidden() {
|
||||||
cache[x] = state{hidden: true}
|
cache[x] = state{hidden: true}
|
||||||
|
@ -351,10 +351,10 @@ func (d *dag) removeVertex(v Drawer) {
|
||||||
delete(d.all, v)
|
delete(d.all, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// topIterate visits each vertex in topological order, in time O(|V| + |E|) and
|
// topWalk visits each vertex in topological order, in time O(|V| + |E|) and
|
||||||
// O(|V|) temporary memory.
|
// O(|V|) temporary memory.
|
||||||
func (d *dag) topIterate(visit func(Drawer)) {
|
func (d *dag) topWalk(visit func(Drawer)) {
|
||||||
// Count indegrees - indegree(v) = len(d.in[v]) for each v.
|
// Count indegrees - indegree(v) = len(d.in[v]) for each vertex v.
|
||||||
// If indegree(v) = 0, enqueue. Total: O(|V|).
|
// If indegree(v) = 0, enqueue. Total: O(|V|).
|
||||||
queue := make([]Drawer, 0, len(d.in))
|
queue := make([]Drawer, 0, len(d.in))
|
||||||
indegree := make(map[Drawer]int)
|
indegree := make(map[Drawer]int)
|
||||||
|
|
|
@ -145,6 +145,32 @@ func (g *Game) Parent(c interface{}) interface{} {
|
||||||
return g.par[c]
|
return g.par[c]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WalkUp visits the component, its parent, its parent, ..., and then g.
|
||||||
|
func (g *Game) WalkUp(component interface{}, visit func(interface{}) error) error {
|
||||||
|
for p := component; p != nil; p = g.Parent(p) {
|
||||||
|
if err := visit(p); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WalkDown visits g, the subcomponent of g, ..., and then the component.
|
||||||
|
func (g *Game) WalkDown(component interface{}, visit func(interface{}) error) error {
|
||||||
|
var stack []interface{}
|
||||||
|
g.dbmu.RLock()
|
||||||
|
for p := component; p != nil; p = g.Parent(p) {
|
||||||
|
stack = append(stack, p)
|
||||||
|
}
|
||||||
|
g.dbmu.RUnlock()
|
||||||
|
for _, p := range stack {
|
||||||
|
if err := visit(p); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Query looks for components having both a given ancestor and implementing
|
// Query looks for components having both a given ancestor and implementing
|
||||||
// a given behaviour (see Behaviors in interface.go). This only returns sensible
|
// a given behaviour (see Behaviors in interface.go). This only returns sensible
|
||||||
// values after LoadAndPrepare. Note that every component is its own ancestor.
|
// values after LoadAndPrepare. Note that every component is its own ancestor.
|
||||||
|
|
11
game/aw.go
11
game/aw.go
|
@ -126,12 +126,13 @@ func (aw *Awakeman) realUpdate() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
par := aw.game.Parent(aw)
|
par := aw.game.Parent(aw)
|
||||||
for p := interface{}(aw); p != nil; p = aw.game.Parent(p) {
|
if err := aw.game.WalkDown(par, func(c interface{}) error {
|
||||||
if r, ok := p.(engine.Registrar); ok {
|
if r, ok := c.(engine.Registrar); ok {
|
||||||
if err := r.Register(bubble, par); err != nil {
|
return r.Register(bubble, par)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if err := engine.PreorderWalk(bubble, func(c, _ interface{}) error {
|
if err := engine.PreorderWalk(bubble, func(c, _ interface{}) error {
|
||||||
if p, ok := c.(engine.Prepper); ok {
|
if p, ok := c.(engine.Prepper); ok {
|
||||||
|
|
|
@ -71,7 +71,12 @@ func (b *Bubble) Prepare(g *engine.Game) error {
|
||||||
func (b *Bubble) Update() error {
|
func (b *Bubble) Update() error {
|
||||||
b.Life--
|
b.Life--
|
||||||
if b.Life <= 0 {
|
if b.Life <= 0 {
|
||||||
b.game.Unregister(b)
|
if err := b.game.WalkUp(b, func(c interface{}) error {
|
||||||
|
b.game.Unregister(b)
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if false { // not using MoveX/MoveY/... because collisions are unnecessary -
|
if false { // not using MoveX/MoveY/... because collisions are unnecessary -
|
||||||
// this is an effect particle, if it overlaps a solid, who cares
|
// this is an effect particle, if it overlaps a solid, who cares
|
||||||
|
|
Loading…
Reference in a new issue