| 1 | // Copyright (C) 2021 The Qt Company Ltd. |
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
| 3 | |
| 4 | #include "converterthread.h" |
| 5 | |
| 6 | #include <QtQuick3DAssetImport/private/qssgassetimportmanager_p.h> |
| 7 | |
| 8 | #include <QFuture> |
| 9 | #include <QtConcurrent/QtConcurrent> |
| 10 | |
| 11 | ConverterThread::ConverterThread(QObject *parent) : QThread(parent) { } |
| 12 | |
| 13 | ConverterThread::~ConverterThread() |
| 14 | { |
| 15 | mutex.lock(); |
| 16 | abort = true; |
| 17 | condition.wakeOne(); |
| 18 | mutex.unlock(); |
| 19 | wait(); |
| 20 | } |
| 21 | |
| 22 | void ConverterThread::convert(QStringList filenames, QDir outputPath, QJsonObject options) |
| 23 | { |
| 24 | QMutexLocker locker(&mutex); |
| 25 | |
| 26 | // Write settings |
| 27 | m_filenames = filenames; |
| 28 | m_outputPath = outputPath; |
| 29 | m_options = options; |
| 30 | |
| 31 | if (!isRunning()) { |
| 32 | start(LowPriority); |
| 33 | } else { |
| 34 | condition.wakeOne(); |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | void ConverterThread::run() |
| 39 | { |
| 40 | forever { |
| 41 | if (abort) |
| 42 | return; |
| 43 | |
| 44 | // Copy settings |
| 45 | mutex.lock(); |
| 46 | auto filenames = m_filenames; |
| 47 | auto outputPath = m_outputPath; |
| 48 | auto options = m_options; |
| 49 | mutex.unlock(); |
| 50 | |
| 51 | emit convertStart(text: QString("Converting %1 files..." ).arg(a: filenames.size())); |
| 52 | |
| 53 | std::atomic<int> failCounter = 0; |
| 54 | std::atomic<int> fileCounter = 0; |
| 55 | const int numFiles = filenames.size(); |
| 56 | |
| 57 | auto convertFile = [&](const QString &filename) { |
| 58 | if (abort) |
| 59 | return; |
| 60 | QString error; |
| 61 | QSSGAssetImportManager assetImporter; |
| 62 | assetImporter.importFile(filename, outputPath, options, error: &error); |
| 63 | const size_t ctr = ++fileCounter; |
| 64 | failCounter += error.isEmpty() ? 0 : 1; |
| 65 | |
| 66 | if (!error.isEmpty()) |
| 67 | emit convertUpdate( |
| 68 | text: QString("[%1/%2] Failed to convert '%3': %4" ).arg(args: QString::number(ctr), args: QString::number(numFiles), args: filename, args&: error)); |
| 69 | else |
| 70 | emit convertUpdate( |
| 71 | text: QString("[%1/%2] Successfully converted '%3'" ).arg(args: QString::number(ctr), args: QString::number(numFiles), args: filename)); |
| 72 | }; |
| 73 | |
| 74 | // Convert in parallel |
| 75 | QtConcurrent::blockingMap(sequence&: filenames, map&: convertFile); |
| 76 | |
| 77 | if (failCounter > 0) |
| 78 | emit convertDone(text: QString("\nConversion done, failed to convert %1 of %2 files" ) |
| 79 | .arg(args: QString::number(failCounter), args: QString::number(numFiles))); |
| 80 | else |
| 81 | emit convertDone(text: QString("\nSuccessfully converted all files!" )); |
| 82 | |
| 83 | // Abort or wait for signal |
| 84 | mutex.lock(); |
| 85 | if (!abort) |
| 86 | condition.wait(lockedMutex: &mutex); |
| 87 | mutex.unlock(); |
| 88 | } |
| 89 | } |
| 90 | |