App: guard individual import tasks during shutdown

This commit is contained in:
Marco Allegretti 2026-02-13 18:55:33 +01:00
parent 4b7655bc6b
commit cca49615d6

View file

@ -731,31 +731,55 @@ void App::importAllGames()
void App::importFromSteam()
{
if (m_importing)
if (m_importing || m_shuttingDown.load())
return;
setImporting(true);
setImportStatus(tr("Scanning Steam library..."));
[[maybe_unused]] auto future = QtConcurrent::run([this]() {
[[maybe_unused]] auto future = QtConcurrent::run([self = QPointer<App>(this)]() {
if (!self || self->m_shuttingDown.load()) {
return;
}
SteamImporter importer;
QList<Game *> games = importer.importGames();
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
delete game;
}
return;
}
QThread *appThread = self->thread();
for (Game *game : games) {
game->moveToThread(this->thread());
game->setParent(nullptr);
if (game) {
game->moveToThread(appThread);
game->setParent(nullptr);
}
}
QMetaObject::invokeMethod(
this,
[this, games]() {
for (Game *game : games) {
m_gameModel->addGame(game);
self.data(),
[self, games]() {
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
if (game) {
game->deleteLater();
}
}
return;
}
setImportStatus(tr("Steam import complete: %1 games found").arg(games.count()));
setImporting(false);
saveLibrary();
Q_EMIT importCompleted(games.count());
for (Game *game : games) {
if (game) {
self->m_gameModel->addGame(game);
}
}
self->setImportStatus(self->tr("Steam import complete: %1 games found").arg(games.count()));
self->setImporting(false);
self->saveLibrary();
Q_EMIT self->importCompleted(games.count());
},
Qt::QueuedConnection);
});
@ -763,31 +787,55 @@ void App::importFromSteam()
void App::importFromLutris()
{
if (m_importing)
if (m_importing || m_shuttingDown.load())
return;
setImporting(true);
setImportStatus(tr("Scanning Lutris library..."));
[[maybe_unused]] auto future = QtConcurrent::run([this]() {
[[maybe_unused]] auto future = QtConcurrent::run([self = QPointer<App>(this)]() {
if (!self || self->m_shuttingDown.load()) {
return;
}
LutrisImporter importer;
QList<Game *> games = importer.importGames();
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
delete game;
}
return;
}
QThread *appThread = self->thread();
for (Game *game : games) {
game->moveToThread(this->thread());
game->setParent(nullptr);
if (game) {
game->moveToThread(appThread);
game->setParent(nullptr);
}
}
QMetaObject::invokeMethod(
this,
[this, games]() {
for (Game *game : games) {
m_gameModel->addGame(game);
self.data(),
[self, games]() {
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
if (game) {
game->deleteLater();
}
}
return;
}
setImportStatus(tr("Lutris import complete: %1 games found").arg(games.count()));
setImporting(false);
saveLibrary();
Q_EMIT importCompleted(games.count());
for (Game *game : games) {
if (game) {
self->m_gameModel->addGame(game);
}
}
self->setImportStatus(self->tr("Lutris import complete: %1 games found").arg(games.count()));
self->setImporting(false);
self->saveLibrary();
Q_EMIT self->importCompleted(games.count());
},
Qt::QueuedConnection);
});
@ -795,31 +843,55 @@ void App::importFromLutris()
void App::importFromHeroic()
{
if (m_importing)
if (m_importing || m_shuttingDown.load())
return;
setImporting(true);
setImportStatus(tr("Scanning Heroic library..."));
[[maybe_unused]] auto future = QtConcurrent::run([this]() {
[[maybe_unused]] auto future = QtConcurrent::run([self = QPointer<App>(this)]() {
if (!self || self->m_shuttingDown.load()) {
return;
}
HeroicImporter importer;
QList<Game *> games = importer.importGames();
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
delete game;
}
return;
}
QThread *appThread = self->thread();
for (Game *game : games) {
game->moveToThread(this->thread());
game->setParent(nullptr);
if (game) {
game->moveToThread(appThread);
game->setParent(nullptr);
}
}
QMetaObject::invokeMethod(
this,
[this, games]() {
for (Game *game : games) {
m_gameModel->addGame(game);
self.data(),
[self, games]() {
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
if (game) {
game->deleteLater();
}
}
return;
}
setImportStatus(tr("Heroic import complete: %1 games found").arg(games.count()));
setImporting(false);
saveLibrary();
Q_EMIT importCompleted(games.count());
for (Game *game : games) {
if (game) {
self->m_gameModel->addGame(game);
}
}
self->setImportStatus(self->tr("Heroic import complete: %1 games found").arg(games.count()));
self->setImporting(false);
self->saveLibrary();
Q_EMIT self->importCompleted(games.count());
},
Qt::QueuedConnection);
});
@ -827,31 +899,55 @@ void App::importFromHeroic()
void App::importFromDesktop()
{
if (m_importing)
if (m_importing || m_shuttingDown.load())
return;
setImporting(true);
setImportStatus(tr("Scanning desktop entries..."));
[[maybe_unused]] auto future = QtConcurrent::run([this]() {
[[maybe_unused]] auto future = QtConcurrent::run([self = QPointer<App>(this)]() {
if (!self || self->m_shuttingDown.load()) {
return;
}
DesktopImporter importer;
QList<Game *> games = importer.importGames();
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
delete game;
}
return;
}
QThread *appThread = self->thread();
for (Game *game : games) {
game->moveToThread(this->thread());
game->setParent(nullptr);
if (game) {
game->moveToThread(appThread);
game->setParent(nullptr);
}
}
QMetaObject::invokeMethod(
this,
[this, games]() {
for (Game *game : games) {
m_gameModel->addGame(game);
self.data(),
[self, games]() {
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
if (game) {
game->deleteLater();
}
}
return;
}
setImportStatus(tr("Desktop import complete: %1 games found").arg(games.count()));
setImporting(false);
saveLibrary();
Q_EMIT importCompleted(games.count());
for (Game *game : games) {
if (game) {
self->m_gameModel->addGame(game);
}
}
self->setImportStatus(self->tr("Desktop import complete: %1 games found").arg(games.count()));
self->setImporting(false);
self->saveLibrary();
Q_EMIT self->importCompleted(games.count());
},
Qt::QueuedConnection);
});
@ -859,31 +955,55 @@ void App::importFromDesktop()
void App::importFromBottles()
{
if (m_importing)
if (m_importing || m_shuttingDown.load())
return;
setImporting(true);
setImportStatus(tr("Scanning Bottles..."));
[[maybe_unused]] auto future = QtConcurrent::run([this]() {
[[maybe_unused]] auto future = QtConcurrent::run([self = QPointer<App>(this)]() {
if (!self || self->m_shuttingDown.load()) {
return;
}
BottlesImporter importer;
QList<Game *> games = importer.importGames();
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
delete game;
}
return;
}
QThread *appThread = self->thread();
for (Game *game : games) {
game->moveToThread(this->thread());
game->setParent(nullptr);
if (game) {
game->moveToThread(appThread);
game->setParent(nullptr);
}
}
QMetaObject::invokeMethod(
this,
[this, games]() {
for (Game *game : games) {
m_gameModel->addGame(game);
self.data(),
[self, games]() {
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
if (game) {
game->deleteLater();
}
}
return;
}
setImportStatus(tr("Bottles import complete: %1 games found").arg(games.count()));
setImporting(false);
saveLibrary();
Q_EMIT importCompleted(games.count());
for (Game *game : games) {
if (game) {
self->m_gameModel->addGame(game);
}
}
self->setImportStatus(self->tr("Bottles import complete: %1 games found").arg(games.count()));
self->setImporting(false);
self->saveLibrary();
Q_EMIT self->importCompleted(games.count());
},
Qt::QueuedConnection);
});
@ -891,31 +1011,55 @@ void App::importFromBottles()
void App::importFromFlatpak()
{
if (m_importing)
if (m_importing || m_shuttingDown.load())
return;
setImporting(true);
setImportStatus(tr("Scanning Flatpak games..."));
[[maybe_unused]] auto future = QtConcurrent::run([this]() {
[[maybe_unused]] auto future = QtConcurrent::run([self = QPointer<App>(this)]() {
if (!self || self->m_shuttingDown.load()) {
return;
}
FlatpakImporter importer;
QList<Game *> games = importer.importGames();
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
delete game;
}
return;
}
QThread *appThread = self->thread();
for (Game *game : games) {
game->moveToThread(this->thread());
game->setParent(nullptr);
if (game) {
game->moveToThread(appThread);
game->setParent(nullptr);
}
}
QMetaObject::invokeMethod(
this,
[this, games]() {
for (Game *game : games) {
m_gameModel->addGame(game);
self.data(),
[self, games]() {
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
if (game) {
game->deleteLater();
}
}
return;
}
setImportStatus(tr("Flatpak import complete: %1 games found").arg(games.count()));
setImporting(false);
saveLibrary();
Q_EMIT importCompleted(games.count());
for (Game *game : games) {
if (game) {
self->m_gameModel->addGame(game);
}
}
self->setImportStatus(self->tr("Flatpak import complete: %1 games found").arg(games.count()));
self->setImporting(false);
self->saveLibrary();
Q_EMIT self->importCompleted(games.count());
},
Qt::QueuedConnection);
});
@ -923,31 +1067,55 @@ void App::importFromFlatpak()
void App::importFromItch()
{
if (m_importing)
if (m_importing || m_shuttingDown.load())
return;
setImporting(true);
setImportStatus(tr("Scanning itch.io library..."));
[[maybe_unused]] auto future = QtConcurrent::run([this]() {
[[maybe_unused]] auto future = QtConcurrent::run([self = QPointer<App>(this)]() {
if (!self || self->m_shuttingDown.load()) {
return;
}
ItchImporter importer;
QList<Game *> games = importer.importGames();
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
delete game;
}
return;
}
QThread *appThread = self->thread();
for (Game *game : games) {
game->moveToThread(this->thread());
game->setParent(nullptr);
if (game) {
game->moveToThread(appThread);
game->setParent(nullptr);
}
}
QMetaObject::invokeMethod(
this,
[this, games]() {
for (Game *game : games) {
m_gameModel->addGame(game);
self.data(),
[self, games]() {
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
if (game) {
game->deleteLater();
}
}
return;
}
setImportStatus(tr("itch.io import complete: %1 games found").arg(games.count()));
setImporting(false);
saveLibrary();
Q_EMIT importCompleted(games.count());
for (Game *game : games) {
if (game) {
self->m_gameModel->addGame(game);
}
}
self->setImportStatus(self->tr("itch.io import complete: %1 games found").arg(games.count()));
self->setImporting(false);
self->saveLibrary();
Q_EMIT self->importCompleted(games.count());
},
Qt::QueuedConnection);
});
@ -955,31 +1123,55 @@ void App::importFromItch()
void App::importFromLegendary()
{
if (m_importing)
if (m_importing || m_shuttingDown.load())
return;
setImporting(true);
setImportStatus(tr("Scanning Legendary library..."));
[[maybe_unused]] auto future = QtConcurrent::run([this]() {
[[maybe_unused]] auto future = QtConcurrent::run([self = QPointer<App>(this)]() {
if (!self || self->m_shuttingDown.load()) {
return;
}
LegendaryImporter importer;
QList<Game *> games = importer.importGames();
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
delete game;
}
return;
}
QThread *appThread = self->thread();
for (Game *game : games) {
game->moveToThread(this->thread());
game->setParent(nullptr);
if (game) {
game->moveToThread(appThread);
game->setParent(nullptr);
}
}
QMetaObject::invokeMethod(
this,
[this, games]() {
for (Game *game : games) {
m_gameModel->addGame(game);
self.data(),
[self, games]() {
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
if (game) {
game->deleteLater();
}
}
return;
}
setImportStatus(tr("Legendary import complete: %1 games found").arg(games.count()));
setImporting(false);
saveLibrary();
Q_EMIT importCompleted(games.count());
for (Game *game : games) {
if (game) {
self->m_gameModel->addGame(game);
}
}
self->setImportStatus(self->tr("Legendary import complete: %1 games found").arg(games.count()));
self->setImporting(false);
self->saveLibrary();
Q_EMIT self->importCompleted(games.count());
},
Qt::QueuedConnection);
});
@ -987,31 +1179,55 @@ void App::importFromLegendary()
void App::importFromRetroArch()
{
if (m_importing)
if (m_importing || m_shuttingDown.load())
return;
setImporting(true);
setImportStatus(tr("Scanning RetroArch playlists..."));
[[maybe_unused]] auto future = QtConcurrent::run([this]() {
[[maybe_unused]] auto future = QtConcurrent::run([self = QPointer<App>(this)]() {
if (!self || self->m_shuttingDown.load()) {
return;
}
RetroArchImporter importer;
QList<Game *> games = importer.importGames();
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
delete game;
}
return;
}
QThread *appThread = self->thread();
for (Game *game : games) {
game->moveToThread(this->thread());
game->setParent(nullptr);
if (game) {
game->moveToThread(appThread);
game->setParent(nullptr);
}
}
QMetaObject::invokeMethod(
this,
[this, games]() {
for (Game *game : games) {
m_gameModel->addGame(game);
self.data(),
[self, games]() {
if (!self || self->m_shuttingDown.load()) {
for (Game *game : games) {
if (game) {
game->deleteLater();
}
}
return;
}
setImportStatus(tr("RetroArch import complete: %1 games found").arg(games.count()));
setImporting(false);
saveLibrary();
Q_EMIT importCompleted(games.count());
for (Game *game : games) {
if (game) {
self->m_gameModel->addGame(game);
}
}
self->setImportStatus(self->tr("RetroArch import complete: %1 games found").arg(games.count()));
self->setImporting(false);
self->saveLibrary();
Q_EMIT self->importCompleted(games.count());
},
Qt::QueuedConnection);
});