void applyToEachNodePO(NodeTree& nt, const NodeAction& action) { /// PO-traversal requires two stacks std::stack<VisualNode*> stk_1; std::stack<VisualNode*> stk_2; auto* root = nt.getRoot(); auto& na = nt.getNA(); stk_1.push(root); while (stk_1.size() > 0) { auto* node = stk_1.top(); stk_1.pop(); stk_2.push(node); for (auto i = 0u; i < node->getNumberOfChildren(); ++i) { auto kid = node->getChild(na, i); stk_1.push(kid); } } while (stk_2.size() > 0) { auto* node = stk_2.top(); stk_2.pop(); action(node); } }
void highlightSubtrees(NodeTree& nt, const std::vector<VisualNode*>& nodes) { QMutexLocker lock(&nt.getMutex()); auto& na = nt.getNA(); auto* root = nt.getRoot(); root->unhideAll(na); { QMutexLocker lock(&nt.getLayoutMutex()); root->layout(na); } // unhighlight all applyToEachNode(nt, [](VisualNode* n) { n->setHighlighted(false); }); for (auto node : nodes) { node->setHighlighted(true); } // TODO: hide not highlighted // HideNotHighlightedCursor hnhc(root, na); // PostorderNodeVisitor<HideNotHighlightedCursor>(hnhc).run(); nt.treeModified(); }
int calculateMaxDepth(const NodeTree& nt) { const auto& na = nt.getNA(); const auto* root = nt.getRoot(); return calcDepth(na, root); }
Statistics gatherNodeStats(NodeTree& nt) { Statistics stats; auto* root = nt.getRoot(); applyToEachNode(nt, root, [&stats](VisualNode* n) { switch (n->getStatus()) { case SOLVED: stats.solutions += 1; break; case FAILED: stats.failures += 1; break; case BRANCH: stats.choices += 1; break; case UNDETERMINED: stats.undetermined += 1; break; default: break; } }); stats.maxDepth = calculateMaxDepth(nt); return stats; }