mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 00:55:09 -07:00
[DeckList] Extract deck metadata XML serialization (#7306)
* [DeckList] Extract deck metadata XML serialization DeckList still serialized its metadata inline: a ten-branch readElement dispatch and a static writeMetadata that duplicated the tree plumbing. The metadata arms (name, comments, format, timestamp, banner card, playmat, tags) move to DeckListMetadataXml free functions over the Metadata struct, leaving DeckList::readElement a thin dispatcher between metadata, zones and sideboard plans. The playmat clamping helper moves along with the element that uses it. * [DeckList] Make deck metadata XML serialization instance methods * [DeckList] Inline deck metadata XML serialization Fold DeckList::Metadata::readElement and write back into deck_list.cpp alongside isEmpty(), and drop the separate deck_list_metadata_xml translation unit. The metadata arms are instance methods of the nested Metadata struct, so keeping them in the same file as its other method keeps the class from being scattered across two .cpp files; the rest of the refactor (readElement as a thin dispatcher, element-wise reads, clamped playmat params) is unchanged. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
69d32ed853
commit
5ace88c111
2 changed files with 94 additions and 67 deletions
|
|
@ -43,6 +43,78 @@ bool DeckList::Metadata::isEmpty() const
|
||||||
return name.isEmpty() && comments.isEmpty() && bannerCard.isEmpty() && tags.isEmpty() && playmat.card.isEmpty();
|
return name.isEmpty() && comments.isEmpty() && bannerCard.isEmpty() && tags.isEmpty() && playmat.card.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DeckList::Metadata::readElement(QXmlStreamReader *xml, const QString &childName)
|
||||||
|
{
|
||||||
|
if (childName == "lastLoadedTimestamp") {
|
||||||
|
lastLoadedTimestamp = xml->readElementText();
|
||||||
|
} else if (childName == "deckname") {
|
||||||
|
name = xml->readElementText();
|
||||||
|
} else if (childName == "format") {
|
||||||
|
gameFormat = xml->readElementText();
|
||||||
|
} else if (childName == "comments") {
|
||||||
|
comments = xml->readElementText();
|
||||||
|
} else if (childName == "bannerCard") {
|
||||||
|
QString providerId = xml->attributes().value("providerId").toString();
|
||||||
|
QString cardName = xml->readElementText();
|
||||||
|
bannerCard = {cardName, providerId};
|
||||||
|
} else if (childName == "playmatCard") {
|
||||||
|
QString providerId = xml->attributes().value("providerId").toString();
|
||||||
|
// Attributes are read before readElementText consumes the element.
|
||||||
|
QString marginLStr = xml->attributes().value("marginPctL").toString();
|
||||||
|
QString marginRStr = xml->attributes().value("marginPctR").toString();
|
||||||
|
QString vOffStr = xml->attributes().value("verticalOffset").toString();
|
||||||
|
QString zoomStr = xml->attributes().value("zoom").toString();
|
||||||
|
QString cardName = xml->readElementText();
|
||||||
|
playmat.card = {cardName, providerId};
|
||||||
|
// Clamp to the same ranges as the settings dialog and the remote
|
||||||
|
// player-properties path so malformed deck files cannot produce
|
||||||
|
// degenerate art rectangles (e.g. a zoom of 0 dividing by zero).
|
||||||
|
playmat.params.marginPctL = parseClampedParam(marginLStr, 0.07, 0.0, 0.95);
|
||||||
|
playmat.params.marginPctR = parseClampedParam(marginRStr, 0.07, 0.0, 0.95);
|
||||||
|
playmat.params.verticalOffset = parseClampedParam(vOffStr, 0.33, 0.0, 1.0);
|
||||||
|
playmat.params.zoom = parseClampedParam(zoomStr, 1.0, 0.1, 4.0);
|
||||||
|
} else if (childName == "tags") {
|
||||||
|
tags.clear(); // Clear existing tags
|
||||||
|
while (xml->readNextStartElement()) {
|
||||||
|
if (xml->name().toString() == "tag") {
|
||||||
|
tags.append(xml->readElementText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckList::Metadata::write(QXmlStreamWriter *xml) const
|
||||||
|
{
|
||||||
|
xml->writeTextElement("lastLoadedTimestamp", lastLoadedTimestamp);
|
||||||
|
xml->writeTextElement("deckname", name);
|
||||||
|
xml->writeTextElement("format", gameFormat);
|
||||||
|
xml->writeStartElement("bannerCard");
|
||||||
|
xml->writeAttribute("providerId", bannerCard.providerId);
|
||||||
|
xml->writeCharacters(bannerCard.name);
|
||||||
|
xml->writeEndElement();
|
||||||
|
if (!playmat.card.isEmpty()) {
|
||||||
|
xml->writeStartElement("playmatCard");
|
||||||
|
xml->writeAttribute("providerId", playmat.card.providerId);
|
||||||
|
xml->writeAttribute("marginPctL", QString::number(playmat.params.marginPctL, 'f', 4));
|
||||||
|
xml->writeAttribute("marginPctR", QString::number(playmat.params.marginPctR, 'f', 4));
|
||||||
|
xml->writeAttribute("verticalOffset", QString::number(playmat.params.verticalOffset, 'f', 4));
|
||||||
|
xml->writeAttribute("zoom", QString::number(playmat.params.zoom, 'f', 4));
|
||||||
|
xml->writeCharacters(playmat.card.name);
|
||||||
|
xml->writeEndElement();
|
||||||
|
}
|
||||||
|
xml->writeTextElement("comments", comments);
|
||||||
|
|
||||||
|
// Write tags
|
||||||
|
xml->writeStartElement("tags");
|
||||||
|
for (const QString &tag : tags) {
|
||||||
|
xml->writeTextElement("tag", tag);
|
||||||
|
}
|
||||||
|
xml->writeEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
DeckList::DeckList()
|
DeckList::DeckList()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -77,43 +149,10 @@ bool DeckList::readElement(QXmlStreamReader *xml)
|
||||||
{
|
{
|
||||||
const QString childName = xml->name().toString();
|
const QString childName = xml->name().toString();
|
||||||
if (xml->isStartElement()) {
|
if (xml->isStartElement()) {
|
||||||
if (childName == "lastLoadedTimestamp") {
|
if (metadata.readElement(xml, childName)) {
|
||||||
metadata.lastLoadedTimestamp = xml->readElementText();
|
return true;
|
||||||
} else if (childName == "deckname") {
|
}
|
||||||
metadata.name = xml->readElementText();
|
if (childName == "zone") {
|
||||||
} else if (childName == "format") {
|
|
||||||
metadata.gameFormat = xml->readElementText();
|
|
||||||
} else if (childName == "comments") {
|
|
||||||
metadata.comments = xml->readElementText();
|
|
||||||
} else if (childName == "bannerCard") {
|
|
||||||
QString providerId = xml->attributes().value("providerId").toString();
|
|
||||||
QString cardName = xml->readElementText();
|
|
||||||
metadata.bannerCard = {cardName, providerId};
|
|
||||||
} else if (childName == "playmatCard") {
|
|
||||||
QString providerId = xml->attributes().value("providerId").toString();
|
|
||||||
QString marginLStr = xml->attributes().value("marginPctL").toString();
|
|
||||||
QString marginRStr = xml->attributes().value("marginPctR").toString();
|
|
||||||
QString vOffStr = xml->attributes().value("verticalOffset").toString();
|
|
||||||
QString zoomStr = xml->attributes().value("zoom").toString();
|
|
||||||
QString cardName = xml->readElementText();
|
|
||||||
PlaymatInfo playmat;
|
|
||||||
playmat.card = {cardName, providerId};
|
|
||||||
// Clamp to the same ranges as the settings dialog and the remote
|
|
||||||
// player-properties path so malformed deck files cannot produce
|
|
||||||
// degenerate art rectangles (e.g. a zoom of 0 dividing by zero).
|
|
||||||
playmat.params.marginPctL = parseClampedParam(marginLStr, 0.07, 0.0, 0.95);
|
|
||||||
playmat.params.marginPctR = parseClampedParam(marginRStr, 0.07, 0.0, 0.95);
|
|
||||||
playmat.params.verticalOffset = parseClampedParam(vOffStr, 0.33, 0.0, 1.0);
|
|
||||||
playmat.params.zoom = parseClampedParam(zoomStr, 1.0, 0.1, 4.0);
|
|
||||||
metadata.playmat = playmat;
|
|
||||||
} else if (childName == "tags") {
|
|
||||||
metadata.tags.clear(); // Clear existing tags
|
|
||||||
while (xml->readNextStartElement()) {
|
|
||||||
if (xml->name().toString() == "tag") {
|
|
||||||
metadata.tags.append(xml->readElementText());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (childName == "zone") {
|
|
||||||
tree.readZoneElement(xml);
|
tree.readZoneElement(xml);
|
||||||
} else if (childName == "sideboard_plan") {
|
} else if (childName == "sideboard_plan") {
|
||||||
SideboardPlan newSideboardPlan;
|
SideboardPlan newSideboardPlan;
|
||||||
|
|
@ -127,41 +166,12 @@ bool DeckList::readElement(QXmlStreamReader *xml)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeMetadata(QXmlStreamWriter *xml, const DeckList::Metadata &metadata)
|
|
||||||
{
|
|
||||||
xml->writeTextElement("lastLoadedTimestamp", metadata.lastLoadedTimestamp);
|
|
||||||
xml->writeTextElement("deckname", metadata.name);
|
|
||||||
xml->writeTextElement("format", metadata.gameFormat);
|
|
||||||
xml->writeStartElement("bannerCard");
|
|
||||||
xml->writeAttribute("providerId", metadata.bannerCard.providerId);
|
|
||||||
xml->writeCharacters(metadata.bannerCard.name);
|
|
||||||
xml->writeEndElement();
|
|
||||||
if (!metadata.playmat.card.isEmpty()) {
|
|
||||||
xml->writeStartElement("playmatCard");
|
|
||||||
xml->writeAttribute("providerId", metadata.playmat.card.providerId);
|
|
||||||
xml->writeAttribute("marginPctL", QString::number(metadata.playmat.params.marginPctL, 'f', 4));
|
|
||||||
xml->writeAttribute("marginPctR", QString::number(metadata.playmat.params.marginPctR, 'f', 4));
|
|
||||||
xml->writeAttribute("verticalOffset", QString::number(metadata.playmat.params.verticalOffset, 'f', 4));
|
|
||||||
xml->writeAttribute("zoom", QString::number(metadata.playmat.params.zoom, 'f', 4));
|
|
||||||
xml->writeCharacters(metadata.playmat.card.name);
|
|
||||||
xml->writeEndElement();
|
|
||||||
}
|
|
||||||
xml->writeTextElement("comments", metadata.comments);
|
|
||||||
|
|
||||||
// Write tags
|
|
||||||
xml->writeStartElement("tags");
|
|
||||||
for (const QString &tag : metadata.tags) {
|
|
||||||
xml->writeTextElement("tag", tag);
|
|
||||||
}
|
|
||||||
xml->writeEndElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeckList::write(QXmlStreamWriter *xml) const
|
void DeckList::write(QXmlStreamWriter *xml) const
|
||||||
{
|
{
|
||||||
xml->writeStartElement("cockatrice_deck");
|
xml->writeStartElement("cockatrice_deck");
|
||||||
xml->writeAttribute("version", "1");
|
xml->writeAttribute("version", "1");
|
||||||
|
|
||||||
writeMetadata(xml, metadata);
|
metadata.write(xml);
|
||||||
|
|
||||||
// Write zones
|
// Write zones
|
||||||
tree.write(xml);
|
tree.write(xml);
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,23 @@ public:
|
||||||
* @brief Checks if all values (except for lastLoadedTimestamp) in the metadata is empty.
|
* @brief Checks if all values (except for lastLoadedTimestamp) in the metadata is empty.
|
||||||
*/
|
*/
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads a single deck metadata element from a Cockatrice deck XML stream.
|
||||||
|
*
|
||||||
|
* @param xml Reader positioned at the element.
|
||||||
|
* @param childName Name of the current element.
|
||||||
|
* @return true if a metadata element was consumed, false if @p childName is
|
||||||
|
* not a metadata element.
|
||||||
|
*/
|
||||||
|
bool readElement(QXmlStreamReader *xml, const QString &childName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes the deck metadata section of a Cockatrice deck XML file.
|
||||||
|
*
|
||||||
|
* @param xml Writer to append the metadata elements to.
|
||||||
|
*/
|
||||||
|
void write(QXmlStreamWriter *xml) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue