mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 01:23:24 -08:00
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [CardDB] Drop the CardInfo self pointer The weak self pointer had to be assigned right after every construction, and a missed assignment silently stopped change notifications. CardInfo is always owned by a QSharedPointer, so it now derives from QEnableSharedFromThis<CardInfo> and asks for sharedFromThis() instead: nothing to initialize, and the CardSet cycle stays broken. CardSet::newInstance() also loses the commented-out self-pointer assignment left over from the same design. * [CardDB] Pin the cardInfoChanged contract without the self pointer Dropping CardInfo's self pointer moved change notifications onto QEnableSharedFromThis, so the signal now rests on the card being owned by a QSharedPointer. Two tests pin that down: - A property change on a card owned by a CardDatabase still emits cardInfoChanged() carrying that card, which is what the card database views and models listen to. - clone() starts out unowned, so a change to the clone is reported as the clone's and must not reach the original's observers. * [CardDB] Treat an unowned CardInfo as a bug, not a no-op Every CardInfo is built inside a QSharedPointer (both factory overloads and clone()), and no constructor notifies anyone, so sharedFromThis() is always available by the time addToSet() or a setter runs. Assert that and warn in a released build, instead of silently skipping the notification or the set append. The copy constructor keeps its explicit QEnableSharedFromThis initializer: GCC's -Wextra warns about the uninitialized base in every translation unit that copies a CardInfo otherwise. A comment there records that the clone deliberately starts unowned. * [CardDB] Break the CardInfo <-> CardSet cycle on reload CardSet is a QList<CardInfoPtr> and CardInfo::addToSet() appends the card to its sets, while a card keeps a CardSetPtr per printing in setsToPrintings. The sets therefore hold strong references back to the cards, and the previous database snapshot stayed alive after a reload, so RSS grew by roughly a second database on every reload. Empty the sets before the cards are dropped: CardDatabase::clear() and swapInDatabaseData() clear the sets before replacing the containers, and removeCard() detaches the card from its sets, so nothing keeps a card alive on behalf of a set once the database lets go of it. Two tests pin the behaviour: a reload and a clear() must drop the last strong reference to a card from the previous snapshot. * [CardDB] Keep the set detach in one place clear() and swapInDatabaseData() both emptied every set before dropping the cards, so share that as detachSetMembership() instead of two copies that have to stay in sync. removeCard() now detaches through the first printing of each set directly, the same way CardInfo::newInstance() appends, instead of an inner loop that always breaks after the first item. Because clear() empties the sets up front, its per-card detach was walking every card's printings to remove it from sets that were already empty. Split removeCard() into the per-card detach and unindexCard(), and let clear() call only the latter. * [CardDB] Test that removeCard detaches the card from its set removeCard() is the one teardown path a caller can trigger for a single card (the token editor uses it), and it now detaches the card from its sets as well. Without that detach the set's strong CardInfoPtr keeps the removed card alive forever, which is exactly what the reload and clear tests pin for the whole-snapshot paths. The test loads the fixture, removes Cat, and requires the card to be gone from the CAT set and to be destroyed once the test drops its own reference. * [Servatrice] Drop the settings cache from the logger #7602 removed #include "settingscache.h" from server_logger.cpp but left isLoggingEnabled() reading settingsCache, so master no longer compiles: the servatrice target fails on the undeclared global and server_logger_test, which compiles the same file without main.cpp, fails to link it. The same commit made reloadConfig() the single place that stores writelog and the log filters, precisely so logging threads stop reading the global QSettings. isLoggingEnabled() now mirrors logMessage() and reads those members instead: the console is a sink of its own, and the logfile needs an open file plus writelog. The mutex is mutable so the const query can take it. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
579 lines
22 KiB
C++
579 lines
22 KiB
C++
#ifndef CARD_INFO_H
|
|
#define CARD_INFO_H
|
|
|
|
#include "format/format_legality_rules.h"
|
|
#include "lazy_properties_hash.h"
|
|
#include "printing/printing_info.h"
|
|
|
|
#include <QByteArray>
|
|
#include <QChar>
|
|
#include <QEnableSharedFromThis>
|
|
#include <QHash>
|
|
#include <QList>
|
|
#include <QLoggingCategory>
|
|
#include <QMap>
|
|
#include <QMetaType>
|
|
#include <QObject>
|
|
#include <QSet>
|
|
#include <QSharedPointer>
|
|
#include <QString>
|
|
#include <QStringList>
|
|
#include <qtmetamacros.h>
|
|
#include <utility>
|
|
|
|
inline Q_LOGGING_CATEGORY(CardInfoLog, "card_info");
|
|
|
|
class CardInfo;
|
|
class CardSet;
|
|
class CardRelation;
|
|
|
|
typedef QSharedPointer<CardInfo> CardInfoPtr;
|
|
typedef QSharedPointer<CardSet> CardSetPtr;
|
|
typedef QSharedPointer<FormatRules> FormatRulesPtr;
|
|
typedef QMap<QString, QList<PrintingInfo>> SetToPrintingsMap;
|
|
|
|
typedef QHash<QString, CardInfoPtr> CardNameMap;
|
|
typedef QHash<QString, CardSetPtr> SetNameMap;
|
|
typedef QHash<QString, FormatRulesPtr> FormatRulesNameMap;
|
|
|
|
Q_DECLARE_METATYPE(CardInfoPtr)
|
|
|
|
/**
|
|
* @class CardInfo
|
|
* @ingroup Cards
|
|
*
|
|
* @brief Represents a card and its associated metadata, properties, and relationships.
|
|
*
|
|
* CardInfo holds both static information (name, text, flags) and dynamic data
|
|
* (properties, set memberships, relationships). It also integrates with
|
|
* signals/slots, allowing observers to react to property or visual updates.
|
|
*
|
|
* Each CardInfo may belong to multiple sets through its printings, and can
|
|
* be related to other cards through defined relationships.
|
|
*/
|
|
class CardInfo : public QObject, public QEnableSharedFromThis<CardInfo>
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
/**
|
|
* @class CardInfo::UiAttributes
|
|
* @ingroup Cards
|
|
*
|
|
* @brief Attributes of the card that affect display and game logic.
|
|
*/
|
|
struct UiAttributes
|
|
{
|
|
bool cipt = false; ///< Positioning flag used by UI.
|
|
bool landscapeOrientation = false; ///< Orientation flag for rendering.
|
|
int tableRow = 0; ///< Row index in a table or visual representation.
|
|
bool upsideDownArt = false; ///< Whether artwork is flipped for visual purposes.
|
|
};
|
|
|
|
private:
|
|
/** @name Private Card Properties
|
|
* @anchor PrivateCardProperties
|
|
*/
|
|
///@{
|
|
QString name; ///< Full name of the card.
|
|
QString simpleName; ///< Simplified name for fuzzy matching.
|
|
QString text; ///< Text description or rules text of the card.
|
|
bool isToken; ///< Whether this card is a token or not.
|
|
|
|
QMap<QString, QString> localizedNames; ///< Localized card names, keyed by language code.
|
|
QMap<QString, QString> localizedTexts; ///< Localized rules text, keyed by language code.
|
|
|
|
LazyPropertiesHash properties; ///< Key-value store of dynamic card properties.
|
|
|
|
QList<CardRelation *> relatedCards; ///< Forward references to related cards.
|
|
QList<CardRelation *> reverseRelatedCards; ///< Cards that refer back to this card.
|
|
QList<CardRelation *> reverseRelatedCardsToMe; ///< Cards that consider this card as related.
|
|
SetToPrintingsMap setsToPrintings; ///< Mapping from set names to printing variations.
|
|
UiAttributes uiAttributes; ///< Attributes that affect display and game logic
|
|
QString setsNames; ///< Cached, human-readable list of set names.
|
|
QSet<QString> altNames; ///< Cached set of alternate names, used when searching
|
|
///@}
|
|
|
|
public:
|
|
/**
|
|
* @brief Constructs a CardInfo with full initialization.
|
|
*
|
|
* @param _name The name of the card.
|
|
* @param _text Rules text or description of the card.
|
|
* @param _isToken Flag indicating whether the card is a token.
|
|
* @param _properties Arbitrary key-value properties.
|
|
* @param _relatedCards Forward references to related cards.
|
|
* @param _reverseRelatedCards Backward references to related cards.
|
|
* @param _sets Map of set names to printing information.
|
|
* @param _uiAttributes Attributes that affect display and game logic
|
|
* @param _localizedNames Localized card names, keyed by language code.
|
|
* @param _localizedTexts Localized rules text, keyed by language code.
|
|
*/
|
|
explicit CardInfo(const QString &_name,
|
|
const QString &_text,
|
|
bool _isToken,
|
|
const QHash<QString, QString> &_properties,
|
|
const QList<CardRelation *> &_relatedCards,
|
|
const QList<CardRelation *> &_reverseRelatedCards,
|
|
SetToPrintingsMap _sets,
|
|
UiAttributes _uiAttributes,
|
|
QMap<QString, QString> _localizedNames = {},
|
|
QMap<QString, QString> _localizedTexts = {});
|
|
|
|
/**
|
|
* @brief Constructs a CardInfo from a serialized properties blob.
|
|
*
|
|
* Properties stay in @p _propertiesBlob so the QHash<QString, QString> is not
|
|
* built at load time (it is materialized on first query). @p _simpleName and
|
|
* @p _altNames are filled in when empty; the binary cache supplies them to
|
|
* skip the Unicode normalization and the printing scan.
|
|
*
|
|
* @param _name The card name.
|
|
* @param _text Rules text or description of the card.
|
|
* @param _isToken Token flag.
|
|
* @param _propertiesBlob Pre-serialized properties blob (as written by the cache).
|
|
* @param _relatedCards Forward relationships.
|
|
* @param _reverseRelatedCards Reverse relationships.
|
|
* @param _sets Printing information per set.
|
|
* @param _uiAttributes Attributes that affect display and game logic.
|
|
* @param _simpleName Precomputed simplified name; derived from @p _name when empty.
|
|
* @param _altNames Precomputed alternate names; derived from the printings when empty.
|
|
* @param _localizedNames Localized card names, keyed by language code.
|
|
* @param _localizedTexts Localized rules text, keyed by language code.
|
|
*/
|
|
explicit CardInfo(const QString &_name,
|
|
const QString &_text,
|
|
bool _isToken,
|
|
const QByteArray &_propertiesBlob,
|
|
const QList<CardRelation *> &_relatedCards,
|
|
const QList<CardRelation *> &_reverseRelatedCards,
|
|
SetToPrintingsMap _sets,
|
|
UiAttributes _uiAttributes,
|
|
QString _simpleName,
|
|
QSet<QString> _altNames,
|
|
QMap<QString, QString> _localizedNames = {},
|
|
QMap<QString, QString> _localizedTexts = {});
|
|
|
|
/**
|
|
* @brief Copy constructor for CardInfo.
|
|
*
|
|
* Performs a deep copy of properties, sets, and related card lists.
|
|
*
|
|
* @param other Another CardInfo to copy.
|
|
*/
|
|
CardInfo(const CardInfo &other)
|
|
: QObject(other.parent()), QEnableSharedFromThis<CardInfo>(), name(other.name), simpleName(other.simpleName),
|
|
text(other.text), isToken(other.isToken), localizedNames(other.localizedNames),
|
|
localizedTexts(other.localizedTexts), properties(other.properties), relatedCards(other.relatedCards),
|
|
reverseRelatedCards(other.reverseRelatedCards), reverseRelatedCardsToMe(other.reverseRelatedCardsToMe),
|
|
setsToPrintings(other.setsToPrintings), uiAttributes(other.uiAttributes), setsNames(other.setsNames),
|
|
altNames(other.altNames)
|
|
{
|
|
// The copy deliberately starts unowned: the QSharedPointer that wraps it registers the self reference.
|
|
}
|
|
|
|
/**
|
|
* @brief Creates a new instance with only the card name.
|
|
*
|
|
* All other fields are set to defaults.
|
|
*
|
|
* @param _name The card name.
|
|
* @return Shared pointer to the new CardInfo instance.
|
|
*/
|
|
static CardInfoPtr newInstance(const QString &_name);
|
|
|
|
/**
|
|
* @brief Creates a new instance with full initialization.
|
|
*
|
|
* @param _name Name of the card.
|
|
* @param _text Rules text or description.
|
|
* @param _isToken Token flag.
|
|
* @param _properties Arbitrary properties.
|
|
* @param _relatedCards Forward relationships.
|
|
* @param _reverseRelatedCards Reverse relationships.
|
|
* @param _sets Printing information per set.
|
|
* @param _uiAttributes Attributes that affect display and game logic
|
|
* @param _localizedNames Localized card names, keyed by language code.
|
|
* @param _localizedTexts Localized rules text, keyed by language code.
|
|
* @return Shared pointer to the new CardInfo instance.
|
|
*/
|
|
static CardInfoPtr newInstance(const QString &_name,
|
|
const QString &_text,
|
|
bool _isToken,
|
|
const QHash<QString, QString> &_properties,
|
|
const QList<CardRelation *> &_relatedCards,
|
|
const QList<CardRelation *> &_reverseRelatedCards,
|
|
SetToPrintingsMap _sets,
|
|
UiAttributes _uiAttributes,
|
|
QMap<QString, QString> _localizedNames = {},
|
|
QMap<QString, QString> _localizedTexts = {});
|
|
|
|
/**
|
|
* @brief Creates a new instance from a serialized properties blob.
|
|
*
|
|
* The properties stay in blob form, so the QHash<QString, QString> is not
|
|
* built at load time (it is materialized on first query). The derived state
|
|
* is required so it is never recomputed here, and the overload cannot be a
|
|
* candidate for a shorter call that passes a property hash instead of a blob.
|
|
*
|
|
* @param _name Name of the card.
|
|
* @param _text Rules text or description.
|
|
* @param _isToken Token flag.
|
|
* @param _propertiesBlob Serialized properties blob.
|
|
* @param _relatedCards Forward relationships.
|
|
* @param _reverseRelatedCards Reverse relationships.
|
|
* @param _sets Printing information per set.
|
|
* @param _uiAttributes Attributes that affect display and game logic.
|
|
* @param _simpleName Precomputed simplified name; pass {} to derive it from
|
|
* @p _name.
|
|
* @param _altNames Precomputed alternate names; pass {} to derive them from
|
|
* the printings.
|
|
* @param _appendToSets When true, the card is appended to each of
|
|
* its CardSets. Pass false when building cards in parallel so the
|
|
* (non-thread-safe) set membership is populated in a later
|
|
* single-threaded pass.
|
|
* @param _localizedNames Localized card names, keyed by language code.
|
|
* @param _localizedTexts Localized rules text, keyed by language code.
|
|
* @return Shared pointer to the new CardInfo instance.
|
|
*/
|
|
static CardInfoPtr newInstance(const QString &_name,
|
|
const QString &_text,
|
|
bool _isToken,
|
|
QByteArray _propertiesBlob,
|
|
const QList<CardRelation *> &_relatedCards,
|
|
const QList<CardRelation *> &_reverseRelatedCards,
|
|
SetToPrintingsMap _sets,
|
|
UiAttributes _uiAttributes,
|
|
QString _simpleName,
|
|
QSet<QString> _altNames,
|
|
bool _appendToSets,
|
|
QMap<QString, QString> _localizedNames = {},
|
|
QMap<QString, QString> _localizedTexts = {});
|
|
|
|
/**
|
|
* @brief Clones the current CardInfo instance.
|
|
*
|
|
* Uses the copy constructor; the copy is managed by its own shared pointer.
|
|
*
|
|
* @return Shared pointer to the cloned CardInfo.
|
|
*/
|
|
[[nodiscard]] CardInfoPtr clone() const
|
|
{
|
|
return CardInfoPtr(new CardInfo(*this));
|
|
}
|
|
|
|
/** @name Basic Properties Accessors */ //@{
|
|
[[nodiscard]] inline const QString &getName() const
|
|
{
|
|
return name;
|
|
}
|
|
[[nodiscard]] const QString &getSimpleName() const
|
|
{
|
|
return simpleName;
|
|
}
|
|
const QSet<QString> &getAltNames() const
|
|
{
|
|
return altNames;
|
|
}
|
|
[[nodiscard]] const QString &getText() const
|
|
{
|
|
return text;
|
|
}
|
|
void setText(const QString &_text)
|
|
{
|
|
text = _text;
|
|
notifyChanged();
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the card name in the given language, falling back to the
|
|
* English name when no localization is available.
|
|
*
|
|
* @param lang Language code (e.g. "de", "ja", "zhs").
|
|
* @return The localized name, or the English name as fallback.
|
|
*/
|
|
[[nodiscard]] const QString &getLocalizedName(const QString &lang) const
|
|
{
|
|
const auto it = localizedNames.constFind(lang);
|
|
return it != localizedNames.constEnd() ? it.value() : name;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the rules text in the given language, falling back to the
|
|
* English text when no localization is available.
|
|
*
|
|
* @param lang Language code (e.g. "de", "ja", "zhs").
|
|
* @return The localized text, or the English text as fallback.
|
|
*/
|
|
[[nodiscard]] const QString &getLocalizedText(const QString &lang) const
|
|
{
|
|
const auto it = localizedTexts.constFind(lang);
|
|
return it != localizedTexts.constEnd() ? it.value() : text;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the localized card names keyed by language code.
|
|
*
|
|
* Only languages that have an entry are present; there is no English
|
|
* fallback in this map.
|
|
*/
|
|
[[nodiscard]] const QMap<QString, QString> &getLocalizedNames() const
|
|
{
|
|
return localizedNames;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the localized rules text keyed by language code.
|
|
*
|
|
* Only languages that have an entry are present; there is no English
|
|
* fallback in this map.
|
|
*/
|
|
[[nodiscard]] const QMap<QString, QString> &getLocalizedTexts() const
|
|
{
|
|
return localizedTexts;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the card name for the given language.
|
|
*
|
|
* @param lang Language code.
|
|
* @param _localizedName The localized card name.
|
|
*/
|
|
void setLocalizedName(const QString &lang, const QString &_localizedName)
|
|
{
|
|
if (localizedNames.value(lang) == _localizedName) {
|
|
return;
|
|
}
|
|
localizedNames.insert(lang, _localizedName);
|
|
notifyChanged();
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the rules text for the given language.
|
|
*
|
|
* @param lang Language code.
|
|
* @param _localizedText The localized rules text.
|
|
*/
|
|
void setLocalizedText(const QString &lang, const QString &_localizedText)
|
|
{
|
|
if (localizedTexts.value(lang) == _localizedText) {
|
|
return;
|
|
}
|
|
localizedTexts.insert(lang, _localizedText);
|
|
notifyChanged();
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the language codes for which this card has a localized
|
|
* name or rules text.
|
|
*/
|
|
[[nodiscard]] QStringList localizationLanguages() const
|
|
{
|
|
QStringList languages = localizedNames.keys();
|
|
languages.append(localizedTexts.keys());
|
|
languages.removeDuplicates();
|
|
return languages;
|
|
}
|
|
[[nodiscard]] bool getIsToken() const
|
|
{
|
|
return isToken;
|
|
}
|
|
[[nodiscard]] QStringList getProperties() const
|
|
{
|
|
return properties.keys();
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the properties in their serialized blob form.
|
|
*
|
|
* Cheap while the properties were never materialized (the cache and the XML parsers pass the blob through).
|
|
*/
|
|
[[nodiscard]] QByteArray getPropertiesBlob() const
|
|
{
|
|
return properties.serialized();
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the materialized property hash, forcing deserialization of the blob.
|
|
*
|
|
* Prefer getProperty(), hasProperty() or getPropertiesBlob(), which avoid building the hash.
|
|
*/
|
|
[[nodiscard]] const QHash<QString, QString> &getPropertiesHash() const;
|
|
|
|
[[nodiscard]] QString getProperty(const QString &propertyName) const
|
|
{
|
|
return properties.value(propertyName);
|
|
}
|
|
void setProperty(const QString &_name, const QString &_value);
|
|
[[nodiscard]] bool hasProperty(const QString &propertyName) const
|
|
{
|
|
return properties.contains(propertyName);
|
|
}
|
|
[[nodiscard]] const SetToPrintingsMap &getSets() const
|
|
{
|
|
return setsToPrintings;
|
|
}
|
|
[[nodiscard]] const QString &getSetsNames() const
|
|
{
|
|
return setsNames;
|
|
}
|
|
//@}
|
|
|
|
/** @name Related Cards Accessors */ //@{
|
|
[[nodiscard]] const QList<CardRelation *> &getRelatedCards() const
|
|
{
|
|
return relatedCards;
|
|
}
|
|
[[nodiscard]] const QList<CardRelation *> &getReverseRelatedCards() const
|
|
{
|
|
return reverseRelatedCards;
|
|
}
|
|
[[nodiscard]] const QList<CardRelation *> &getReverseRelatedCards2Me() const
|
|
{
|
|
return reverseRelatedCardsToMe;
|
|
}
|
|
[[nodiscard]] QList<CardRelation *> getAllRelatedCards() const
|
|
{
|
|
QList<CardRelation *> result;
|
|
result.append(getRelatedCards());
|
|
result.append(getReverseRelatedCards2Me());
|
|
return result;
|
|
}
|
|
void resetReverseRelatedCards2Me();
|
|
/**
|
|
* @brief Clears the raw relation lists without deleting the CardRelation objects.
|
|
*
|
|
* Callers that schedule the relations for deletion (e.g. CardDatabase::removeCard())
|
|
* must use this to drop the now-dangling pointers from this CardInfo, which may
|
|
* outlive them through external shared pointers.
|
|
*/
|
|
void clearDirectRelations();
|
|
void addReverseRelatedCards2Me(CardRelation *cardRelation)
|
|
{
|
|
reverseRelatedCardsToMe.append(cardRelation);
|
|
}
|
|
//@}
|
|
|
|
/** @name UI Positioning */ //@{
|
|
[[nodiscard]] const UiAttributes &getUiAttributes() const
|
|
{
|
|
return uiAttributes;
|
|
}
|
|
//@}
|
|
|
|
[[nodiscard]] QChar getColorChar() const;
|
|
|
|
/** @name Legacy/Convenience Property Accessors */ //@{
|
|
[[nodiscard]] QString getCardType() const;
|
|
void setCardType(const QString &value);
|
|
[[nodiscard]] QString getCmc() const;
|
|
[[nodiscard]] QString getColors() const;
|
|
void setColors(const QString &value);
|
|
[[nodiscard]] QString getLoyalty() const;
|
|
[[nodiscard]] QString getMainCardType() const;
|
|
[[nodiscard]] QString getManaCost() const;
|
|
[[nodiscard]] QString getPowTough() const;
|
|
void setPowTough(const QString &value);
|
|
//@}
|
|
|
|
/**
|
|
* @brief Returns a version of the card name safe for file storage or fuzzy matching.
|
|
*
|
|
* Removes invalid characters, replaces spacing markers, and normalizes diacritics.
|
|
*
|
|
* @return Corrected card name as a QString.
|
|
*/
|
|
[[nodiscard]] QString getCorrectedName() const;
|
|
|
|
/**
|
|
* @brief Gets the card's legality value for the given format.
|
|
* The legality prop for a format is stored in the property map under the key "format-<name>"
|
|
* @param format The format's name.
|
|
* @return The card's legality value for the format. Empty if not found.
|
|
*/
|
|
[[nodiscard]] QString getLegalityProp(const QString &format) const;
|
|
|
|
/**
|
|
* @brief Checks if the card is legal in the given format.
|
|
* A card is considered legal in a format if its properties map contains an entry for "format-<name>", with value
|
|
* "legal" or "restricted".
|
|
* @param format The format's name. If empty, will always return true.
|
|
* @return Whether the card is legal in the given format.
|
|
*/
|
|
[[nodiscard]] bool isLegalInFormat(const QString &format) const;
|
|
|
|
/**
|
|
* @brief Adds a printing to a specific set.
|
|
*
|
|
* Updates the mapping and refreshes the cached list of set names.
|
|
*
|
|
* @param _set The set to which the card should be added.
|
|
* @param _info Optional printing information.
|
|
*/
|
|
void addToSet(const CardSetPtr &_set, const PrintingInfo &_info = PrintingInfo());
|
|
|
|
/**
|
|
* @brief Combines legality properties from a provided map.
|
|
*
|
|
* Useful for merging format legality flags from multiple sources.
|
|
*
|
|
* @param props Key-value mapping of format legalities.
|
|
*/
|
|
void combineLegalities(const QHash<QString, QString> &props);
|
|
|
|
/**
|
|
* @brief Refreshes all cached fields that are calculated from the contained sets and printings.
|
|
*
|
|
* Typically called after adding or modifying set memberships or printings.
|
|
*/
|
|
void refreshCachedSets();
|
|
|
|
/**
|
|
* @brief Simplifies a name for fuzzy matching.
|
|
*
|
|
* Converts to lowercase, removes punctuation/spacing.
|
|
*
|
|
* @param name Original name string.
|
|
* @return Simplified name string.
|
|
*/
|
|
static QString simplifyName(const QString &name);
|
|
|
|
private:
|
|
/**
|
|
* @brief Emits cardInfoChanged() with a strong reference to this card.
|
|
*
|
|
* A CardInfo is always owned by a QSharedPointer, so the self reference is always available; a released
|
|
* build that somehow finds it missing warns rather than emitting a null card.
|
|
*/
|
|
void notifyChanged();
|
|
|
|
/**
|
|
* @brief Refreshes the cached, human-readable list of set names.
|
|
*
|
|
* Typically called after adding or modifying set memberships.
|
|
*/
|
|
void refreshCachedSetNames();
|
|
|
|
/**
|
|
* @brief Refreshes the cached list of alt names for the card.
|
|
*
|
|
* Typically called after adding or modifying the contained printings.
|
|
*/
|
|
void refreshCachedAltNames();
|
|
|
|
signals:
|
|
/**
|
|
* @brief Emitted when a pixmap for this card has been updated or finished loading.
|
|
*
|
|
* @param printing Specific printing for which the pixmap has updated.
|
|
*/
|
|
void pixmapUpdated(const PrintingInfo &printing);
|
|
|
|
/**
|
|
* @brief Emitted when card properties or state have changed.
|
|
*
|
|
* @param card Shared pointer to the CardInfo instance that changed.
|
|
*/
|
|
void cardInfoChanged(CardInfoPtr card);
|
|
};
|
|
#endif
|