mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
linking refactor
This commit is contained in:
+89
-80
@@ -22,66 +22,74 @@ AddCardAction::AddCardAction(Set& set)
|
||||
, action(ADD, make_intrusive<Card>(*set.game), set.cards)
|
||||
{}
|
||||
|
||||
AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const CardP& card)
|
||||
: CardListAction(set)
|
||||
, action(ar, card, set.cards)
|
||||
{}
|
||||
|
||||
AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const vector<CardP>& cards)
|
||||
: CardListAction(set)
|
||||
, action(ar, cards, set.cards)
|
||||
{}
|
||||
{
|
||||
// If we are adding cards, resolve any uid conflicts
|
||||
// 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<String, CardP> all_existing_cards;
|
||||
unordered_set<String> 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<String, CardP> all_added_uids;
|
||||
for (size_t pos = 0; pos < action.steps.size(); ++pos) {
|
||||
CardP card = action.steps[pos].item;
|
||||
all_added_uids.insert({ card->uid, card });
|
||||
}
|
||||
// Cycle on the added cards
|
||||
unordered_map<String, CardP> all_added_uids_copy(all_added_uids);
|
||||
FOR_EACH(added_pair, all_added_uids_copy) {
|
||||
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;
|
||||
String new_uid = generate_uid();
|
||||
added_card->uid = new_uid;
|
||||
all_added_uids.insert({ new_uid, added_card });
|
||||
// Update links on linked cards
|
||||
LINK_PAIRS(linked_pairs, added_card);
|
||||
FOR_EACH(linked_pair, linked_pairs) {
|
||||
String& linked_uid = linked_pair.first.get();
|
||||
String& linked_relation = linked_pair.second.get();
|
||||
if (linked_uid.empty()) continue;
|
||||
// If it's an added card, replace 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);
|
||||
if (linked_index < 0) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_1_("not enough free links", linked_card->identification()));
|
||||
}
|
||||
else {
|
||||
String relation(linked_card->getLinkedRelation(linked_index));
|
||||
card_link_actions.push_back(make_intrusive<OneWayLinkCardsAction>(set, linked_card, new_uid, relation, linked_index));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String AddCardAction::getName(bool to_undo) const {
|
||||
return action.getName();
|
||||
}
|
||||
|
||||
void AddCardAction::perform(bool to_undo) {
|
||||
// If we are adding cards, resolve any uid conflicts
|
||||
// (If we are re-adding cards, from a remove undo, there shouldn't be any uid conflicts)
|
||||
// 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 && !to_undo) {
|
||||
// Tally existing unique ids
|
||||
unordered_map<String, CardP> all_existing_uids;
|
||||
FOR_EACH(card, set.cards) {
|
||||
all_existing_uids.insert({ card->uid, card });
|
||||
}
|
||||
// Tally added unique ids
|
||||
unordered_map<String, CardP> all_added_uids;
|
||||
for (size_t pos = 0; pos < action.steps.size(); ++pos) {
|
||||
CardP card = action.steps[pos].item;
|
||||
all_added_uids.insert({ card->uid, card });
|
||||
}
|
||||
FOR_EACH(added_pair, all_added_uids) {
|
||||
String old_uid = added_pair.first;
|
||||
CardP added_card = added_pair.second;
|
||||
// Assign new unique ids
|
||||
if (all_existing_uids.find(old_uid) != all_existing_uids.end()) {
|
||||
String new_uid = generate_uid();
|
||||
added_card->uid = new_uid;
|
||||
all_added_uids.insert({ new_uid, added_card });
|
||||
// Update links on linked cards
|
||||
OTHER_LINKED_PAIRS(linked_pairs, added_card);
|
||||
FOR_EACH(linked_pair, linked_pairs) {
|
||||
String& linked_uid = linked_pair.first.get();
|
||||
String& linked_relation = linked_pair.second.get();
|
||||
if (linked_uid.empty()) continue;
|
||||
// If it's an added card, replace the link
|
||||
if (all_added_uids.find(linked_uid) != all_added_uids.end()) {
|
||||
all_added_uids.at(linked_uid)->updateLink(old_uid, new_uid);
|
||||
}
|
||||
// Otherwise, if it's an existing card, copy the link
|
||||
else if (all_existing_uids.find(linked_uid) != all_existing_uids.end()) {
|
||||
all_existing_uids.at(linked_uid)->copyLink(set, old_uid, new_uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add or remove cards
|
||||
action.perform(set.cards, to_undo);
|
||||
// Update card links
|
||||
for (int i = 0; i < card_link_actions.size(); ++i) {
|
||||
card_link_actions[i]->perform(to_undo);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Reorder cards
|
||||
@@ -108,39 +116,40 @@ void ReorderCardsAction::perform(bool to_undo) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Link cards
|
||||
|
||||
LinkCardsAction::LinkCardsAction(Set& set, const CardP& selected_card, vector<CardP>& linked_cards, const String& selected_relation, const String& linked_relation)
|
||||
: CardListAction(set), selected_card(selected_card), linked_cards(linked_cards), selected_relation(selected_relation), linked_relation(linked_relation)
|
||||
{}
|
||||
OneWayLinkCardsAction::OneWayLinkCardsAction(Set& set, CardP& card, const String& uid, const String& relation, int index)
|
||||
: CardListAction(set), card(card), uid(uid), relation(relation)
|
||||
{
|
||||
switch (index) {
|
||||
case 1: {
|
||||
linked_uid = &card->linked_card_1;
|
||||
linked_relation = &card->linked_relation_1;
|
||||
return;
|
||||
}
|
||||
case 2: {
|
||||
linked_uid = &card->linked_card_2;
|
||||
linked_relation = &card->linked_relation_2;
|
||||
return;
|
||||
}
|
||||
case 3: {
|
||||
linked_uid = &card->linked_card_3;
|
||||
linked_relation = &card->linked_relation_3;
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
linked_uid = &card->linked_card_4;
|
||||
linked_relation = &card->linked_relation_4;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String LinkCardsAction::getName(bool to_undo) const {
|
||||
return _("Link cards");
|
||||
String OneWayLinkCardsAction::getName(bool to_undo) const {
|
||||
return _("Change link");
|
||||
}
|
||||
|
||||
void LinkCardsAction::perform(bool to_undo) {
|
||||
if (!to_undo) {
|
||||
selected_card->link(set, linked_cards, selected_relation, linked_relation);
|
||||
} else {
|
||||
selected_card->unlink(linked_cards);
|
||||
}
|
||||
}
|
||||
|
||||
UnlinkCardsAction::UnlinkCardsAction(Set& set, const CardP& selected_card, CardP& unlinked_card)
|
||||
: CardListAction(set), selected_card(selected_card), unlinked_card(unlinked_card)
|
||||
{}
|
||||
|
||||
String UnlinkCardsAction::getName(bool to_undo) const {
|
||||
return _("Unlink card");
|
||||
}
|
||||
|
||||
void UnlinkCardsAction::perform(bool to_undo) {
|
||||
if (!to_undo) {
|
||||
pair<String, String> relations = selected_card->unlink(unlinked_card);
|
||||
selected_relation = relations.first;
|
||||
unlinked_relation = relations.second;
|
||||
}
|
||||
else {
|
||||
selected_card->link(set, unlinked_card, selected_relation, unlinked_relation);
|
||||
}
|
||||
void OneWayLinkCardsAction::perform(bool to_undo) {
|
||||
swap(*linked_uid, uid);
|
||||
swap(*linked_relation, relation);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Change stylesheet
|
||||
@@ -236,7 +245,7 @@ String ChangeCardUIDAction::getName(bool to_undo) const {
|
||||
}
|
||||
void ChangeCardUIDAction::perform(bool to_undo) {
|
||||
FOR_EACH(c, set.cards) {
|
||||
c->updateLink(card->uid, uid);
|
||||
c->updateLinkedUID(card->uid, uid);
|
||||
}
|
||||
swap(card->uid, uid);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user