WalkDown strategy: https://stackoverflow.com/questions/5278580/non-recursive-depth-first-search-algorithm WalkDown calls the given function on the node and all of its children in a depth-first manner over all of the children, sequentially in the current goroutine. It stops walking the current branch
(fun func(n Node) bool)
| 487 | // method is called for every node after the given function, which enables nodes |
| 488 | // to also traverse additional nodes, like widget parts. |
| 489 | func (n *NodeBase) WalkDown(fun func(n Node) bool) { |
| 490 | if n.This == nil { |
| 491 | return |
| 492 | } |
| 493 | tm := map[Node]int{} // traversal map |
| 494 | start := n.This |
| 495 | cur := start |
| 496 | tm[cur] = -1 |
| 497 | outer: |
| 498 | for { |
| 499 | cb := cur.AsTree() |
| 500 | if cb.This != nil && fun(cur) { // false return means stop |
| 501 | cb.This.NodeWalkDown(fun) |
| 502 | if cb.HasChildren() { |
| 503 | tm[cur] = 0 // 0 for no fields |
| 504 | nxt := cb.Child(0) |
| 505 | if nxt != nil && nxt.AsTree().This != nil { |
| 506 | cur = nxt.AsTree().This |
| 507 | tm[cur] = -1 |
| 508 | continue |
| 509 | } |
| 510 | } |
| 511 | } else { |
| 512 | tm[cur] = cb.NumChildren() |
| 513 | } |
| 514 | // if we get here, we're in the ascent branch -- move to the right and then up |
| 515 | for { |
| 516 | cb := cur.AsTree() // may have changed, so must get again |
| 517 | curChild := tm[cur] |
| 518 | if (curChild + 1) < cb.NumChildren() { |
| 519 | curChild++ |
| 520 | tm[cur] = curChild |
| 521 | nxt := cb.Child(curChild) |
| 522 | if nxt != nil && nxt.AsTree().This != nil { |
| 523 | cur = nxt.AsTree().This |
| 524 | tm[cur] = -1 |
| 525 | continue outer |
| 526 | } |
| 527 | continue |
| 528 | } |
| 529 | delete(tm, cur) |
| 530 | // couldn't go right, move up.. |
| 531 | if cur == start { |
| 532 | break outer // done! |
| 533 | } |
| 534 | parent := cb.Parent |
| 535 | if parent == nil || parent == cur { // shouldn't happen, but does.. |
| 536 | // fmt.Printf("nil / cur parent %v\n", par) |
| 537 | break outer |
| 538 | } |
| 539 | cur = parent |
| 540 | } |
| 541 | } |
| 542 | } |
| 543 | |
| 544 | // NodeWalkDown is a placeholder implementation of [Node.NodeWalkDown] |
| 545 | // that does nothing. |