diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.cpp index 196416cde..efe20595b 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.cpp @@ -41,13 +41,19 @@ QList DecklistNodeTree::getCardNodes(const QSet result; - for (auto *zoneNode : getZoneNodes(restrictToZones)) { - for (auto *cardNode : *zoneNode) { - auto *cardCardNode = dynamic_cast(cardNode); - if (cardCardNode) { - result.append(cardCardNode); + std::function collectCards = [&collectCards, + &result](const InnerDecklistNode *node) { + for (int i = 0; i < node->size(); i++) { + if (auto *card = dynamic_cast(node->at(i))) { + result.append(card); + } else if (auto *inner = dynamic_cast(node->at(i))) { + collectCards(inner); } } + }; + + for (auto *zoneNode : getZoneNodes(restrictToZones)) { + collectCards(zoneNode); } return result; @@ -160,13 +166,22 @@ bool DecklistNodeTree::deleteNode(AbstractDecklistNode *node, InnerDecklistNode void DecklistNodeTree::forEachCard(const std::function &func) const { - // Support for this is only possible if the internal structure - // doesn't get more complicated. + // Cards nested in custom zones are reported with their top-level board zone + // so that callers can classify cards by board (main/side/maybeboard/tokens). + std::function walk = [&func, &walk](InnerDecklistNode *boardZone, + InnerDecklistNode *node) { + for (int i = 0; i < node->size(); i++) { + if (auto *card = dynamic_cast(node->at(i))) { + func(boardZone, card); + } else if (auto *inner = dynamic_cast(node->at(i))) { + walk(boardZone, inner); + } + } + }; + for (int i = 0; i < root->size(); i++) { - InnerDecklistNode *node = dynamic_cast(root->at(i)); - for (int j = 0; j < node->size(); j++) { - DecklistCardNode *card = dynamic_cast(node->at(j)); - func(node, card); + if (auto *zone = dynamic_cast(root->at(i))) { + walk(zone, zone); } } } diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h index 8ef0b18a5..eae20aa23 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h @@ -78,9 +78,10 @@ public: bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = nullptr); /** - * @brief Apply a function to every card in the deck tree. This can modify the cards. + * @brief Applies a function to every card in the deck tree. This can modify the cards. * - * @param func Function taking (zone node, card node). + * @param func Function taking (top-level board zone node, card node). Cards nested + * in custom zones are reported with their board zone. */ void forEachCard(const std::function &func) const;