From 8cc17abecc7804be49c642ee295589a1c6defb93 Mon Sep 17 00:00:00 2001 From: GenevensiS <66968533+G-e-n-e-v-e-n-s-i-S@users.noreply.github.com> Date: Mon, 4 May 2026 02:21:33 +0200 Subject: [PATCH] add card uid map --- src/data/action/set.cpp | 24 +++--- src/data/card.cpp | 133 ++++++++++++++++++++++------------ src/data/card.hpp | 12 +-- src/data/set.cpp | 15 +++- src/data/set.hpp | 25 ++++--- src/gui/card_link_window.cpp | 8 +- src/gui/control/card_list.cpp | 6 +- src/gui/print_window.cpp | 2 +- src/gui/set/window.cpp | 3 +- 9 files changed, 138 insertions(+), 90 deletions(-) diff --git a/src/data/action/set.cpp b/src/data/action/set.cpp index 2d435d98..9ef6f56e 100644 --- a/src/data/action/set.cpp +++ b/src/data/action/set.cpp @@ -30,13 +30,6 @@ AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const vector& // We always assume uid conflicts occur because a card was copy-pasted into the same set, // and never because two different cards randomly got assigned the same uid if (!action.adding) return; - // Tally existing unique ids - unordered_map all_existing_cards; - unordered_set all_existing_uids; - FOR_EACH(card, set.cards) { - all_existing_cards.insert({ card->uid, card }); - all_existing_uids.insert(card->uid); - } // Tally added unique ids unordered_map all_added_uids; for (size_t pos = 0; pos < action.steps.size(); ++pos) { @@ -49,7 +42,7 @@ AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const vector& String old_uid = added_pair.first; CardP added_card = added_pair.second; // Assign new unique id if necessary - if (all_existing_cards.find(old_uid) == all_existing_cards.end()) continue; + if (set.card_uids.find(old_uid) == set.card_uids.end()) continue; String new_uid = generate_uid(); added_card->uid = new_uid; all_added_uids.insert({ new_uid, added_card }); @@ -58,14 +51,14 @@ AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const vector& FOR_EACH(linked_pair, linked_pairs) { String& linked_uid = linked_pair.first.get(); if (linked_uid.empty()) continue; - // If it's an added card, replace the link + // If it's an added card, update the link if (all_added_uids.find(linked_uid) != all_added_uids.end()) { all_added_uids.at(linked_uid)->updateLinkedUID(old_uid, new_uid); } // Otherwise, if it's an existing card, create an action to copy the link - else if (all_existing_cards.find(linked_uid) != all_existing_cards.end()) { - CardP linked_card = all_existing_cards.at(linked_uid); - int linked_index = linked_card->findFreeLink(new_uid, all_existing_uids); + else if (set.card_uids.find(linked_uid) != set.card_uids.end()) { + CardP linked_card = set.card_uids.at(linked_uid); + int linked_index = linked_card->findFreeLink(new_uid, set.card_uids); if (linked_index < 0) { queue_message(MESSAGE_WARNING, _ERROR_1_("not enough free links", linked_card->identification())); } @@ -88,7 +81,9 @@ void AddCardAction::perform(bool to_undo) { // Update card links for (size_t i = 0; i < card_link_actions.size(); ++i) { card_link_actions[i]->perform(to_undo); - } + } + // Update uid map + set.buildUidMap(); } // ----------------------------------------------------------------------------- : Reorder cards @@ -249,7 +244,8 @@ void ChangeCardUIDAction::perform(bool to_undo) { FOR_EACH(c, set.cards) { c->updateLinkedUID(card->uid, uid); } - swap(card->uid, uid); + swap(card->uid, uid); + set.buildUidMap(); } // ----------------------------------------------------------------------------- : Pack types diff --git a/src/data/card.cpp b/src/data/card.cpp index b8972a79..5ad204d1 100644 --- a/src/data/card.cpp +++ b/src/data/card.cpp @@ -67,7 +67,7 @@ bool Card::contains(QuickFilterPart const& query) const { return false; } -vector Card::findFreeLinks(vector& linked_uids, const unordered_set& all_existing_uids) { +vector Card::findFreeLinks(vector& linked_uids, const unordered_map& all_existing_uids) { vector freeIndexes; int count = min(4, (int)linked_uids.size()); LINK_PAIRS(linked_pairs, this); @@ -109,7 +109,7 @@ vector Card::findFreeLinks(vector& linked_uids, const unordered_set } return freeIndexes; } -int Card::findFreeLink(const String& linked_uid, const unordered_set& all_existing_uids) { +int Card::findFreeLink(const String& linked_uid, const unordered_map& all_existing_uids) { vector linked_uids { linked_uid }; return findFreeLinks(linked_uids, all_existing_uids)[0]; } @@ -155,12 +155,26 @@ void Card::updateLinkedUID(const String& old_uid, const String& new_uid) { if (index >= 0) getLinkedUID(index) = new_uid; } -vector Card::getLinkedRelationCards(const vector& cards, const String& linked_relation, bool erase_if_no_card) { +//vector Card::getLinkedRelationCards(const vector& cards, const String& linked_relation, bool erase_if_no_card) { +// vector other_cards; +// vector indexes = findRelationLinks(linked_relation); +// for (size_t i = 0; i < indexes.size(); ++i) { +// String& linked_uid = getLinkedUID(indexes[i]); +// CardP other_card = getUIDCard(cards, linked_uid); +// if (other_card) other_cards.push_back(other_card); +// else if (erase_if_no_card) { +// linked_uid = _(""); +// getLinkedRelation(indexes[i]) = _(""); +// } +// } +// return other_cards; +//} +vector Card::getLinkedRelationCards(const Set& set, const String& linked_relation, bool erase_if_no_card) { vector other_cards; vector indexes = findRelationLinks(linked_relation); for (size_t i = 0; i < indexes.size(); ++i) { String& linked_uid = getLinkedUID(indexes[i]); - CardP other_card = getUIDCard(cards, linked_uid); + CardP other_card = getUIDCard(set, linked_uid); if (other_card) other_cards.push_back(other_card); else if (erase_if_no_card) { linked_uid = _(""); @@ -169,51 +183,76 @@ vector Card::getLinkedRelationCards(const vector& cards, const Str } return other_cards; } -vector Card::getLinkedRelationCards(const Set& set, const String& linked_relation, bool erase_if_no_card) { - return getLinkedRelationCards(set.cards, linked_relation, erase_if_no_card); -} -vector> Card::getLinkedCards(const vector& cards) { - unordered_map links{ - { linked_card_1, linked_relation_1 }, - { linked_card_2, linked_relation_2 }, - { linked_card_3, linked_relation_3 }, - { linked_card_4, linked_relation_4 } - }; +//vector> Card::getLinkedCards(const vector& cards) { +// unordered_map links{ +// { linked_card_1, linked_relation_1 }, +// { linked_card_2, linked_relation_2 }, +// { linked_card_3, linked_relation_3 }, +// { linked_card_4, linked_relation_4 } +// }; +// vector> linked_cards; +// FOR_EACH(other_card, cards) { +// if (links.find(other_card->uid) != links.end()) { +// linked_cards.push_back(make_pair(other_card, links.at(other_card->uid))); +// } +// } +// return linked_cards; +//} +vector> Card::getLinkedCards(const Set& set) { vector> linked_cards; - FOR_EACH(other_card, cards) { - if (links.find(other_card->uid) != links.end()) { - linked_cards.push_back(make_pair(other_card, links.at(other_card->uid))); - } + CardP other_card_1 = getUIDCard(set, linked_card_1); + if (other_card_1) { + linked_cards.push_back(make_pair(other_card_1, linked_relation_1)); + } + CardP other_card_2 = getUIDCard(set, linked_card_2); + if (other_card_2) { + linked_cards.push_back(make_pair(other_card_2, linked_relation_2)); + } + CardP other_card_3 = getUIDCard(set, linked_card_3); + if (other_card_3) { + linked_cards.push_back(make_pair(other_card_3, linked_relation_3)); + } + CardP other_card_4 = getUIDCard(set, linked_card_4); + if (other_card_4) { + linked_cards.push_back(make_pair(other_card_4, linked_relation_4)); } return linked_cards; } -vector> Card::getLinkedCards(const Set& set) { - return getLinkedCards(set.cards); -} -CardP Card::getLinkedOtherFaceCard(const vector& cards) { - unordered_set faces; - if (linked_relation_1 == _("Front Face") || linked_relation_1 == _("Back Face")) faces.emplace(linked_card_1); - if (linked_relation_2 == _("Front Face") || linked_relation_2 == _("Back Face")) faces.emplace(linked_card_2); - if (linked_relation_3 == _("Front Face") || linked_relation_3 == _("Back Face")) faces.emplace(linked_card_3); - if (linked_relation_4 == _("Front Face") || linked_relation_4 == _("Back Face")) faces.emplace(linked_card_4); - FOR_EACH(other_card, cards) { - if (faces.find(other_card->uid) != faces.end()) return other_card; +//CardP Card::getLinkedOtherFaceCard(const vector& cards) { +// unordered_set faces; +// if (linked_relation_1 == _("Front Face") || linked_relation_1 == _("Back Face")) faces.emplace(linked_card_1); +// if (linked_relation_2 == _("Front Face") || linked_relation_2 == _("Back Face")) faces.emplace(linked_card_2); +// if (linked_relation_3 == _("Front Face") || linked_relation_3 == _("Back Face")) faces.emplace(linked_card_3); +// if (linked_relation_4 == _("Front Face") || linked_relation_4 == _("Back Face")) faces.emplace(linked_card_4); +// FOR_EACH(other_card, cards) { +// if (faces.find(other_card->uid) != faces.end()) return other_card; +// } +// return nullptr; +//} +CardP Card::getLinkedOtherFaceCard(const Set& set) { + if (linked_relation_1 == _("Front Face") || linked_relation_1 == _("Back Face")) { + CardP other_card_1 = getUIDCard(set, linked_card_1); + if (other_card_1) return other_card_1; + } + if (linked_relation_2 == _("Front Face") || linked_relation_2 == _("Back Face")) { + CardP other_card_2 = getUIDCard(set, linked_card_2); + if (other_card_2) return other_card_2; + } + if (linked_relation_3 == _("Front Face") || linked_relation_3 == _("Back Face")) { + CardP other_card_3 = getUIDCard(set, linked_card_3); + if (other_card_3) return other_card_3; + } + if (linked_relation_4 == _("Front Face") || linked_relation_4 == _("Back Face")) { + CardP other_card_4 = getUIDCard(set, linked_card_4); + if (other_card_4) return other_card_4; } return nullptr; } -CardP Card::getLinkedOtherFaceCard(const Set& set) { - return getLinkedOtherFaceCard(set.cards); -} void Card::addLink(const Set& set, CardP& linked_card, const String& selected_relation, const String& linked_relation) { - unordered_set all_existing_uids; - FOR_EACH(card, set.cards) { - all_existing_uids.insert(card->uid); - } - - int index = findFreeLink(linked_card->uid, all_existing_uids); + int index = findFreeLink(linked_card->uid, set.card_uids); if (index < 0) { queue_message(MESSAGE_ERROR, _ERROR_1_("not enough free links", identification())); return; @@ -221,7 +260,7 @@ void Card::addLink(const Set& set, CardP& linked_card, const String& selected_re getLinkedUID(index) = linked_card->uid; getLinkedRelation(index) = linked_relation; - index = linked_card->findFreeLink(uid, all_existing_uids); + index = linked_card->findFreeLink(uid, set.card_uids); if (index < 0) { queue_message(MESSAGE_ERROR, _ERROR_1_("not enough free links", linked_card->identification())); } @@ -246,15 +285,19 @@ void Card::removeLink(const CardP& linked_card) } } -CardP Card::getUIDCard(const vector& cards, const String& uid) { - FOR_EACH(card, cards) { - if (card->uid == uid) return card; +//CardP Card::getUIDCard(const vector& cards, const String& uid) { +// FOR_EACH(card, cards) { +// if (card->uid == uid) return card; +// } +// return nullptr; +//} +CardP Card::getUIDCard(const Set& set, const String& uid) { + auto it = set.card_uids.find(uid); + if (it != set.card_uids.end()) { + return it->second; } return nullptr; } -CardP Card::getUIDCard(const Set& set, const String& uid) { - return getUIDCard(set.cards, uid); -} IndexMap& Card::extraDataFor(const StyleSheet& stylesheet) { return extra_data.get(stylesheet.name(), stylesheet.extra_card_fields); diff --git a/src/data/card.hpp b/src/data/card.hpp index 67b10ba1..9dde8cb6 100644 --- a/src/data/card.hpp +++ b/src/data/card.hpp @@ -106,8 +106,8 @@ public: } /// Find the index of a free link slot to write to. Returns -1 if not found. - int findFreeLink (const String& linked_uid, const unordered_set& all_existing_uids); - vector findFreeLinks(vector& linked_uids, const unordered_set& all_existing_uids); + int findFreeLink (const String& linked_uid, const unordered_map& all_existing_uids); + vector findFreeLinks(vector& linked_uids, const unordered_map& all_existing_uids); /// Find the index of a link slot that references the linked_uid. Returns -1 if not found. int findUIDLink(const String& linked_uid); @@ -125,18 +125,18 @@ public: //void updateLinkedRelation(const String& old_relation, const String& new_relation); /// Get the card with the given uid. - static CardP getUIDCard(const vector& cards, const String& uid); + //static CardP getUIDCard(const vector& cards, const String& uid); static CardP getUIDCard(const Set& set, const String& uid); /// Get all the cards linked to this card with the given relation. - vector getLinkedRelationCards(const vector& cards, const String& linked_relation, bool erase_if_no_card = true); + //vector getLinkedRelationCards(const vector& cards, const String& linked_relation, bool erase_if_no_card = true); vector getLinkedRelationCards(const Set& set, const String& linked_relation, bool erase_if_no_card = true); /// Get all the cards linked to this card. - vector> getLinkedCards(const vector& cards); + //vector> getLinkedCards(const vector& cards); vector> getLinkedCards(const Set& set); /// Get the back face or front face of this card. - CardP getLinkedOtherFaceCard(const vector& cards); + //CardP getLinkedOtherFaceCard(const vector& cards); CardP getLinkedOtherFaceCard(const Set& set); /// Link a card to this card. diff --git a/src/data/set.cpp b/src/data/set.cpp index a8294729..e47866a7 100644 --- a/src/data/set.cpp +++ b/src/data/set.cpp @@ -22,6 +22,7 @@ #include // for 0.2.7 fix #include #include +#include #include