Example #1
0
void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) {
    const auto callback = [this, recursion](unsigned* num_entries_out, const std::string& directory,
                                            const std::string& virtual_name) -> bool {
        std::string physical_name = directory + DIR_SEP + virtual_name;

        if (stop_processing)
            return false; // Breaks the callback loop.

        if (!FileUtil::IsDirectory(physical_name)) {
            std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name);
            if (!loader)
                return true;

            std::vector<u8> smdh;
            loader->ReadIcon(smdh);

            u64 program_id = 0;
            loader->ReadProgramId(program_id);

            emit EntryReady({
                new GameListItemPath(QString::fromStdString(physical_name), smdh, program_id),
                new GameListItem(
                    QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
                new GameListItemSize(FileUtil::GetSize(physical_name)),
            });
        } else if (recursion > 0) {
            AddFstEntriesToGameList(physical_name, recursion - 1);
        }

        return true;
    };

    FileUtil::ForeachDirectoryEntry(nullptr, dir_path, callback);
}
Example #2
0
void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, bool deep_scan)
{
    const auto callback = [&](unsigned* num_entries_out,
                              const std::string& directory,
                              const std::string& virtual_name) -> bool {

        std::string physical_name = directory + DIR_SEP + virtual_name;

        if (stop_processing)
            return false; // Breaks the callback loop.

        if (deep_scan && FileUtil::IsDirectory(physical_name)) {
            AddFstEntriesToGameList(physical_name, true);
        } else {
            std::string filename_filename, filename_extension;
            Common::SplitPath(physical_name, nullptr, &filename_filename, &filename_extension);

            Loader::FileType guessed_filetype = Loader::GuessFromExtension(filename_extension);
            if (guessed_filetype == Loader::FileType::Unknown)
                return true;
            Loader::FileType filetype = Loader::IdentifyFile(physical_name);
            if (filetype == Loader::FileType::Unknown) {
                LOG_WARNING(Frontend, "File %s is of indeterminate type and is possibly corrupted.", physical_name.c_str());
                return true;
            }
            if (guessed_filetype != filetype) {
                LOG_WARNING(Frontend, "Filetype and extension of file %s do not match.", physical_name.c_str());
            }

            std::vector<u8> smdh;
            std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(FileUtil::IOFile(physical_name, "rb"), filetype, filename_filename, physical_name);

            if (loader)
                loader->ReadIcon(smdh);

            emit EntryReady({
                new GameListItemPath(QString::fromStdString(physical_name), smdh),
                new GameListItem(QString::fromStdString(Loader::GetFileTypeString(filetype))),
                new GameListItemSize(FileUtil::GetSize(physical_name)),
            });
        }

        return true;
    };

    FileUtil::ForeachDirectoryEntry(nullptr, dir_path, callback);
}
Example #3
0
void GameList::PopulateAsync(const QString& dir_path, bool deep_scan)
{
    if (!FileUtil::Exists(dir_path.toStdString()) || !FileUtil::IsDirectory(dir_path.toStdString())) {
        LOG_ERROR(Frontend, "Could not find game list folder at %s", dir_path.toLocal8Bit().data());
        return;
    }

    tree_view->setEnabled(false);
    // Delete any rows that might already exist if we're repopulating
    item_model->removeRows(0, item_model->rowCount());

    emit ShouldCancelWorker();
    GameListWorker* worker = new GameListWorker(dir_path, deep_scan);

    connect(worker, SIGNAL(EntryReady(QList<QStandardItem*>)), this, SLOT(AddEntry(QList<QStandardItem*>)), Qt::QueuedConnection);
    connect(worker, SIGNAL(Finished()), this, SLOT(DonePopulating()), Qt::QueuedConnection);
    // Use DirectConnection here because worker->Cancel() is thread-safe and we want it to cancel without delay.
    connect(this, SIGNAL(ShouldCancelWorker()), worker, SLOT(Cancel()), Qt::DirectConnection);

    QThreadPool::globalInstance()->start(worker);
    current_worker = std::move(worker);
}