[DeckLoader] make methods static

This commit is contained in:
RickyRister 2026-01-01 01:00:00 -08:00
parent 723f4d3661
commit 44ed3411d0
2 changed files with 109 additions and 114 deletions

View file

@ -29,24 +29,26 @@ DeckLoader::DeckLoader(QObject *parent) : QObject(parent)
{ {
} }
bool DeckLoader::loadFromFile(const QString &fileName, DeckFileFormat::Format fmt, bool userRequest) std::optional<LoadedDeck>
DeckLoader::loadFromFile(const QString &fileName, DeckFileFormat::Format fmt, bool userRequest)
{ {
QFile file(fileName); QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return false; qCWarning(DeckLoaderLog) << "File does not exist:" << fileName;
return std::nullopt;
} }
bool result = false; bool result = false;
DeckList deckList = DeckList(); DeckList deckList;
switch (fmt) { switch (fmt) {
case DeckFileFormat::PlainText: case DeckFileFormat::PlainText:
result = deckList.loadFromFile_Plain(&file); result = deckList.loadFromFile_Plain(&file);
break; break;
case DeckFileFormat::Cockatrice: { case DeckFileFormat::Cockatrice: {
result = deckList.loadFromFile_Native(&file); result = deckList.loadFromFile_Native(&file);
qCInfo(DeckLoaderLog) << "Loaded from" << fileName << "-" << result;
if (!result) { if (!result) {
qCInfo(DeckLoaderLog) << "Retrying as plain format"; qCInfo(DeckLoaderLog) << "Failed to load " << fileName
<< "as cockatrice format; retrying as plain format";
file.seek(0); file.seek(0);
result = deckList.loadFromFile_Plain(&file); result = deckList.loadFromFile_Plain(&file);
fmt = DeckFileFormat::PlainText; fmt = DeckFileFormat::PlainText;
@ -58,120 +60,108 @@ bool DeckLoader::loadFromFile(const QString &fileName, DeckFileFormat::Format fm
break; break;
} }
if (result) {
loadedDeck.deckList = deckList;
loadedDeck.lastLoadInfo = {
.fileName = fileName,
.fileFormat = fmt,
};
if (userRequest) {
updateLastLoadedTimestamp(fileName, fmt);
}
emit deckLoaded();
}
qCInfo(DeckLoaderLog) << "Deck was loaded -" << result;
return result;
}
bool DeckLoader::loadFromFileAsync(const QString &fileName, DeckFileFormat::Format fmt, bool userRequest)
{
auto *watcher = new QFutureWatcher<bool>(this);
connect(watcher, &QFutureWatcher<bool>::finished, this, [this, watcher, fileName, fmt, userRequest]() {
const bool result = watcher->result();
watcher->deleteLater();
if (result) {
loadedDeck.lastLoadInfo = {
.fileName = fileName,
.fileFormat = fmt,
};
if (userRequest) {
updateLastLoadedTimestamp(fileName, fmt);
}
emit deckLoaded();
}
emit loadFinished(result);
});
QFuture<bool> future = QtConcurrent::run([=, this]() {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return false;
}
switch (fmt) {
case DeckFileFormat::PlainText:
return loadedDeck.deckList.loadFromFile_Plain(&file);
case DeckFileFormat::Cockatrice: {
bool result = false;
result = loadedDeck.deckList.loadFromFile_Native(&file);
if (!result) { if (!result) {
file.seek(0); qCWarning(DeckLoaderLog) << "Failed to load " << fileName << "as" << fmt;
return loadedDeck.deckList.loadFromFile_Plain(&file); return std::nullopt;
} }
return result;
}
default:
return false;
break;
}
});
watcher->setFuture(future); LoadedDeck::LoadInfo lastLoadInfo = {
return true; // Return immediately to indicate the async task was started .fileName = fileName,
} .fileFormat = fmt,
bool DeckLoader::loadFromRemote(const QString &nativeString, int remoteDeckId)
{
bool result = loadedDeck.deckList.loadFromString_Native(nativeString);
if (result) {
loadedDeck.lastLoadInfo = {
.remoteDeckId = remoteDeckId,
}; };
LoadedDeck loadedDeck = {deckList, lastLoadInfo};
emit deckLoaded(); if (userRequest) {
updateLastLoadedTimestamp(loadedDeck);
} }
return result;
qCDebug(DeckLoaderLog) << "Loaded deck" << fileName << "with userRequest:" << userRequest;
return loadedDeck;
} }
bool DeckLoader::saveToFile(const QString &fileName, DeckFileFormat::Format fmt) void DeckLoader::loadFromFileAsync(const QString &fileName, DeckFileFormat::Format fmt, bool userRequest)
{
QFuture<void> future = QtConcurrent::run([=, this] {
std::optional<LoadedDeck> deckOpt = loadFromFile(fileName, fmt, userRequest);
if (deckOpt) {
loadedDeck = deckOpt.value();
}
emit loadFinished(deckOpt.has_value());
});
}
std::optional<LoadedDeck> DeckLoader::loadFromRemote(const QString &nativeString, int remoteDeckId)
{
DeckList deckList;
bool success = deckList.loadFromString_Native(nativeString);
if (!success) {
qCWarning(DeckLoaderLog) << "Failed to load remote deck with id" << remoteDeckId << ":" << nativeString;
return std::nullopt;
}
LoadedDeck::LoadInfo lastLoadInfo = {.remoteDeckId = remoteDeckId};
LoadedDeck loadedDeck = {deckList, lastLoadInfo};
qCDebug(DeckLoaderLog) << "Loaded remote deck with id" << remoteDeckId;
return loadedDeck;
}
std::optional<LoadedDeck::LoadInfo>
DeckLoader::saveToFile(const DeckList &deck, const QString &fileName, DeckFileFormat::Format fmt)
{ {
QFile file(fileName); QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
return false; qCWarning(DeckLoaderLog) << "Could not create or open file:" << fileName;
return std::nullopt;
} }
bool result = false; bool success = false;
switch (fmt) { switch (fmt) {
case DeckFileFormat::PlainText: case DeckFileFormat::PlainText:
result = loadedDeck.deckList.saveToFile_Plain(&file); success = deck.saveToFile_Plain(&file);
break; break;
case DeckFileFormat::Cockatrice: case DeckFileFormat::Cockatrice:
result = loadedDeck.deckList.saveToFile_Native(&file); success = deck.saveToFile_Native(&file);
qCInfo(DeckLoaderLog) << "Saving to " << fileName << "-" << result;
break; break;
} }
if (result) {
loadedDeck.lastLoadInfo = {
.fileName = fileName,
.fileFormat = fmt,
};
qCInfo(DeckLoaderLog) << "Deck was saved -" << result;
}
file.flush(); file.flush();
file.close(); file.close();
return result; qCInfo(DeckLoaderLog) << "Saved deck to " << fileName << "with format" << fmt << "-" << success;
if (!success) {
return std::nullopt;
}
LoadedDeck::LoadInfo lastLoadInfo = {fileName, fmt};
return lastLoadInfo;
} }
bool DeckLoader::updateLastLoadedTimestamp(const QString &fileName, DeckFileFormat::Format fmt) bool DeckLoader::saveToFile(const LoadedDeck &deck)
{ {
auto opt = saveToFile(deck.deckList, deck.lastLoadInfo.fileName, deck.lastLoadInfo.fileFormat);
return opt.has_value();
}
bool DeckLoader::saveToNewFile(LoadedDeck &deck, const QString &fileName, DeckFileFormat::Format fmt)
{
std::optional<LoadedDeck::LoadInfo> infoOpt = saveToFile(deck.deckList, fileName, fmt);
if (infoOpt) {
deck.lastLoadInfo = infoOpt.value();
}
return infoOpt.has_value();
}
bool DeckLoader::updateLastLoadedTimestamp(LoadedDeck &deck)
{
QString fileName = deck.lastLoadInfo.fileName;
QFileInfo fileInfo(fileName); QFileInfo fileInfo(fileName);
if (!fileInfo.exists()) { if (!fileInfo.exists()) {
qCWarning(DeckLoaderLog) << "File does not exist:" << fileName; qCWarning(DeckLoaderLog) << "File does not exist:" << fileName;
@ -190,24 +180,19 @@ bool DeckLoader::updateLastLoadedTimestamp(const QString &fileName, DeckFileForm
bool result = false; bool result = false;
// Perform file modifications // Perform file modifications
switch (fmt) { switch (deck.lastLoadInfo.fileFormat) {
case DeckFileFormat::PlainText: case DeckFileFormat::PlainText:
result = loadedDeck.deckList.saveToFile_Plain(&file); result = deck.deckList.saveToFile_Plain(&file);
break; break;
case DeckFileFormat::Cockatrice: case DeckFileFormat::Cockatrice:
loadedDeck.deckList.setLastLoadedTimestamp(QDateTime::currentDateTime().toString()); deck.deckList.setLastLoadedTimestamp(QDateTime::currentDateTime().toString());
result = loadedDeck.deckList.saveToFile_Native(&file); result = deck.deckList.saveToFile_Native(&file);
break; break;
} }
file.close(); // Close the file to ensure changes are flushed file.close(); // Close the file to ensure changes are flushed
if (result) { if (result) {
loadedDeck.lastLoadInfo = {
.fileName = fileName,
.fileFormat = fmt,
};
// Re-open the file and set the original timestamp // Re-open the file and set the original timestamp
if (!file.open(QIODevice::ReadWrite)) { if (!file.open(QIODevice::ReadWrite)) {
qCWarning(DeckLoaderLog) << "Failed to re-open file to set timestamp:" << fileName; qCWarning(DeckLoaderLog) << "Failed to re-open file to set timestamp:" << fileName;
@ -434,8 +419,13 @@ void DeckLoader::saveToStream_DeckZoneCards(QTextStream &out,
} }
} }
bool DeckLoader::convertToCockatriceFormat(const QString &fileName) bool DeckLoader::convertToCockatriceFormat(LoadedDeck &deck)
{ {
QString fileName = deck.lastLoadInfo.fileName;
if (fileName.isEmpty()) {
return false;
}
// Change the file extension to .cod // Change the file extension to .cod
QFileInfo fileInfo(fileName); QFileInfo fileInfo(fileName);
QString newFileName = QDir::toNativeSeparators(fileInfo.path() + "/" + fileInfo.completeBaseName() + ".cod"); QString newFileName = QDir::toNativeSeparators(fileInfo.path() + "/" + fileInfo.completeBaseName() + ".cod");
@ -453,7 +443,7 @@ bool DeckLoader::convertToCockatriceFormat(const QString &fileName)
switch (DeckFileFormat::getFormatFromName(fileName)) { switch (DeckFileFormat::getFormatFromName(fileName)) {
case DeckFileFormat::PlainText: case DeckFileFormat::PlainText:
// Save in Cockatrice's native format // Save in Cockatrice's native format
result = loadedDeck.deckList.saveToFile_Native(&file); result = deck.deckList.saveToFile_Native(&file);
break; break;
case DeckFileFormat::Cockatrice: case DeckFileFormat::Cockatrice:
qCInfo(DeckLoaderLog) << "File is already in Cockatrice format. No conversion needed."; qCInfo(DeckLoaderLog) << "File is already in Cockatrice format. No conversion needed.";
@ -474,7 +464,7 @@ bool DeckLoader::convertToCockatriceFormat(const QString &fileName)
} else { } else {
qCInfo(DeckLoaderLog) << "Original file deleted successfully:" << fileName; qCInfo(DeckLoaderLog) << "Original file deleted successfully:" << fileName;
} }
loadedDeck.lastLoadInfo = { deck.lastLoadInfo = {
.fileName = newFileName, .fileName = newFileName,
.fileFormat = DeckFileFormat::Cockatrice, .fileFormat = DeckFileFormat::Cockatrice,
}; };

View file

@ -20,7 +20,6 @@ class DeckLoader : public QObject
{ {
Q_OBJECT Q_OBJECT
signals: signals:
void deckLoaded();
void loadFinished(bool success); void loadFinished(bool success);
public: public:
@ -53,11 +52,16 @@ public:
return loadedDeck.lastLoadInfo.isEmpty(); return loadedDeck.lastLoadInfo.isEmpty();
} }
bool loadFromFile(const QString &fileName, DeckFileFormat::Format fmt, bool userRequest = false); void loadFromFileAsync(const QString &fileName, DeckFileFormat::Format fmt, bool userRequest);
bool loadFromFileAsync(const QString &fileName, DeckFileFormat::Format fmt, bool userRequest);
bool loadFromRemote(const QString &nativeString, int remoteDeckId); static std::optional<LoadedDeck>
bool saveToFile(const QString &fileName, DeckFileFormat::Format fmt); loadFromFile(const QString &fileName, DeckFileFormat::Format fmt, bool userRequest = false);
bool updateLastLoadedTimestamp(const QString &fileName, DeckFileFormat::Format fmt); static std::optional<LoadedDeck> loadFromRemote(const QString &nativeString, int remoteDeckId);
static std::optional<LoadedDeck::LoadInfo>
saveToFile(const DeckList &deck, const QString &fileName, DeckFileFormat::Format fmt);
static bool saveToFile(const LoadedDeck &deck);
static bool saveToNewFile(LoadedDeck &deck, const QString &fileName, DeckFileFormat::Format fmt);
static QString exportDeckToDecklist(const DeckList &deckList, DecklistWebsite website); static QString exportDeckToDecklist(const DeckList &deckList, DecklistWebsite website);
@ -74,7 +78,7 @@ public:
*/ */
static void printDeckList(QPrinter *printer, const DeckList &deckList); static void printDeckList(QPrinter *printer, const DeckList &deckList);
bool convertToCockatriceFormat(const QString &fileName); static bool convertToCockatriceFormat(LoadedDeck &deck);
LoadedDeck &getDeck() LoadedDeck &getDeck()
{ {
@ -90,6 +94,7 @@ public:
} }
private: private:
static bool updateLastLoadedTimestamp(LoadedDeck &deck);
static void printDeckListNode(QTextCursor *cursor, const InnerDecklistNode *node); static void printDeckListNode(QTextCursor *cursor, const InnerDecklistNode *node);
static void saveToStream_DeckHeader(QTextStream &out, const DeckList &deckList); static void saveToStream_DeckHeader(QTextStream &out, const DeckList &deckList);