mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-05 06:20:03 +02:00
Fix asset server baking not working on *nix
This commit is contained in:
parent
bee666b522
commit
f20aa2e680
4 changed files with 40 additions and 95 deletions
|
@ -12,11 +12,9 @@
|
|||
#include "BakeAssetTask.h"
|
||||
|
||||
#include <QtCore/QThread>
|
||||
#include <QProcess>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <FBXBaker.h>
|
||||
#include <PathUtils.h>
|
||||
#include <JSBaker.h>
|
||||
|
||||
static const int OVEN_STATUS_CODE_SUCCESS { 0 };
|
||||
static const int OVEN_STATUS_CODE_FAIL { 1 };
|
||||
|
@ -48,7 +46,10 @@ void cleanupTempFiles(QString tempOutputDir, std::vector<QString> files) {
|
|||
};
|
||||
|
||||
void BakeAssetTask::run() {
|
||||
_isBaking.store(true);
|
||||
if (_isBaking.exchange(true)) {
|
||||
qWarning() << "Tried to start bake asset task while already baking";
|
||||
return;
|
||||
}
|
||||
|
||||
QString tempOutputDir = PathUtils::generateTemporaryDir();
|
||||
_outputDir = tempOutputDir;
|
||||
|
@ -61,25 +62,27 @@ void BakeAssetTask::run() {
|
|||
"-t", extension,
|
||||
};
|
||||
|
||||
qDebug().noquote() << "Path: " << path << args.join(' ');
|
||||
QProcess* proc = new QProcess();
|
||||
auto _ovenProcess = new QProcess(this);
|
||||
|
||||
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
this, [this, proc, tempOutputDir](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
qDebug() << "Finished process: " << exitCode << exitStatus;
|
||||
qDebug() << "stdout: " << proc->readAllStandardOutput();
|
||||
connect(_ovenProcess, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
this, [this, tempOutputDir](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
qDebug() << "Baking process finished: " << exitCode << exitStatus;
|
||||
|
||||
auto files = _outputDir.entryInfoList(QDir::Files);
|
||||
QVector<QString> outputFiles;
|
||||
for (auto& file : files) {
|
||||
qDebug() << "Output file: " << file.absoluteFilePath();
|
||||
outputFiles.push_back(file.absoluteFilePath());
|
||||
}
|
||||
if (exitStatus == QProcess::CrashExit) {
|
||||
_didFinish.store(true);
|
||||
QString errors = "Fatal error occurred while baking";
|
||||
emit bakeFailed(_assetHash, _assetPath, errors);
|
||||
} else if (exitCode == OVEN_STATUS_CODE_SUCCESS) {
|
||||
auto files = _outputDir.entryInfoList(QDir::Files);
|
||||
QVector<QString> outputFiles;
|
||||
for (auto& file : files) {
|
||||
qDebug() << " Output file: " << file.absoluteFilePath();
|
||||
outputFiles.push_back(file.absoluteFilePath());
|
||||
}
|
||||
|
||||
if (exitCode == OVEN_STATUS_CODE_SUCCESS) {
|
||||
_didFinish.store(true);
|
||||
emit bakeComplete(_assetHash, _assetPath, tempOutputDir, outputFiles);
|
||||
} else if (exitCode == OVEN_STATUS_CODE_ABORT) {
|
||||
} else if (exitStatus == QProcess::NormalExit && exitCode == OVEN_STATUS_CODE_ABORT) {
|
||||
_wasAborted.store(true);
|
||||
emit bakeAborted(_assetHash, _assetPath);
|
||||
} else {
|
||||
|
@ -92,81 +95,22 @@ void BakeAssetTask::run() {
|
|||
errors = errorFile.readAll();
|
||||
errorFile.close();
|
||||
} else {
|
||||
errors = "Unknown error occurred";
|
||||
errors = "Unknown error occurred while baking";
|
||||
}
|
||||
}
|
||||
emit bakeFailed(_assetHash, _assetPath, errors);
|
||||
}
|
||||
|
||||
});
|
||||
connect(proc, &QProcess::errorOccurred, this, []() {
|
||||
qDebug() << "Error occurred :(";
|
||||
});
|
||||
connect(proc, &QProcess::started, this, []() {
|
||||
qDebug() << "Process started";
|
||||
});
|
||||
|
||||
proc->start(path, args, QIODevice::ReadOnly);
|
||||
proc->waitForStarted();
|
||||
proc->waitForFinished();
|
||||
|
||||
return;
|
||||
|
||||
qRegisterMetaType<QVector<QString> >("QVector<QString>");
|
||||
TextureBakerThreadGetter fn = []() -> QThread* { return QThread::currentThread(); };
|
||||
|
||||
if (_assetPath.endsWith(".fbx")) {
|
||||
_baker = std::unique_ptr<FBXBaker> {
|
||||
new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir)
|
||||
};
|
||||
} else if (_assetPath.endsWith(".js", Qt::CaseInsensitive)) {
|
||||
_baker = std::unique_ptr<JSBaker>{
|
||||
new JSBaker(QUrl("file:///" + _filePath), tempOutputDir)
|
||||
};
|
||||
} else {
|
||||
_baker = std::unique_ptr<TextureBaker> {
|
||||
new TextureBaker(QUrl("file:///" + _filePath), image::TextureUsage::CUBE_TEXTURE,
|
||||
tempOutputDir)
|
||||
};
|
||||
}
|
||||
|
||||
QEventLoop loop;
|
||||
connect(_baker.get(), &Baker::finished, &loop, &QEventLoop::quit);
|
||||
connect(_baker.get(), &Baker::aborted, &loop, &QEventLoop::quit);
|
||||
QMetaObject::invokeMethod(_baker.get(), "bake", Qt::QueuedConnection);
|
||||
loop.exec();
|
||||
|
||||
if (_baker->wasAborted()) {
|
||||
qDebug() << "Aborted baking: " << _assetHash << _assetPath;
|
||||
|
||||
_wasAborted.store(true);
|
||||
|
||||
cleanupTempFiles(tempOutputDir, _baker->getOutputFiles());
|
||||
|
||||
emit bakeAborted(_assetHash, _assetPath);
|
||||
} else if (_baker->hasErrors()) {
|
||||
qDebug() << "Failed to bake: " << _assetHash << _assetPath << _baker->getErrors();
|
||||
|
||||
auto errors = _baker->getErrors().join('\n'); // Join error list into a single string for convenience
|
||||
|
||||
_didFinish.store(true);
|
||||
|
||||
cleanupTempFiles(tempOutputDir, _baker->getOutputFiles());
|
||||
|
||||
emit bakeFailed(_assetHash, _assetPath, errors);
|
||||
} else {
|
||||
auto vectorOutputFiles = QVector<QString>::fromStdVector(_baker->getOutputFiles());
|
||||
|
||||
qDebug() << "Finished baking: " << _assetHash << _assetPath << vectorOutputFiles;
|
||||
|
||||
_didFinish.store(true);
|
||||
|
||||
emit bakeComplete(_assetHash, _assetPath, tempOutputDir, vectorOutputFiles);
|
||||
}
|
||||
qDebug() << "Starting oven for " << _assetPath;
|
||||
_ovenProcess->start(path, args, QIODevice::ReadOnly);
|
||||
_ovenProcess->waitForStarted();
|
||||
_ovenProcess->waitForFinished();
|
||||
}
|
||||
|
||||
void BakeAssetTask::abort() {
|
||||
if (_baker) {
|
||||
_baker->abort();
|
||||
if (!_wasAborted.exchange(true)) {
|
||||
_ovenProcess.terminate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
#include <QtCore/QObject>
|
||||
#include <QtCore/QRunnable>
|
||||
#include <QDir>
|
||||
#include <QProcess>
|
||||
|
||||
#include <AssetUtils.h>
|
||||
#include <Baker.h>
|
||||
|
||||
class BakeAssetTask : public QObject, public QRunnable {
|
||||
Q_OBJECT
|
||||
|
@ -46,7 +46,7 @@ private:
|
|||
AssetPath _assetPath;
|
||||
QString _filePath;
|
||||
QDir _outputDir;
|
||||
std::unique_ptr<Baker> _baker;
|
||||
QProcess _ovenProcess { nullptr };
|
||||
std::atomic<bool> _wasAborted { false };
|
||||
std::atomic<bool> _didFinish { false };
|
||||
};
|
||||
|
|
|
@ -67,7 +67,7 @@ QString PathUtils::generateTemporaryDir() {
|
|||
for (auto i = 0; i < 64; ++i) {
|
||||
auto now = std::chrono::system_clock::now().time_since_epoch().count();
|
||||
auto dirName = TEMP_DIR_FORMAT.arg(appName).arg(qApp->applicationPid()).arg(now);
|
||||
QDir tempDir = rootTempDir.filePath(appName + "-" + QString::number(now));
|
||||
QDir tempDir = rootTempDir.filePath(dirName);
|
||||
if (tempDir.mkpath(".")) {
|
||||
return tempDir.absolutePath();
|
||||
}
|
||||
|
@ -83,32 +83,27 @@ int PathUtils::removeTemporaryDirs(QString appName) {
|
|||
|
||||
auto dirName = TEMP_DIR_FORMAT.arg(appName).arg("*").arg("*");
|
||||
qDebug() << "Dirname format is: " << dirName;
|
||||
auto pid = qApp->applicationPid();
|
||||
|
||||
QDir rootTempDir = QDir::tempPath();
|
||||
qDebug() << "Temp dir is: " << rootTempDir;
|
||||
auto dirs = rootTempDir.entryInfoList({ dirName }, QDir::Dirs);
|
||||
int removed = 0;
|
||||
for (auto& dir : dirs) {
|
||||
auto dirName = dir.fileName();
|
||||
auto absoluteDirPath = QDir(dir.absoluteFilePath());
|
||||
qDebug() << " Deleting: " << dirName << absoluteDirPath;
|
||||
QRegularExpression re { "^" + QRegularExpression::escape(appName) + "\\-(?<pid>\\d+)\\-(?<timestamp>\\d+)$" };
|
||||
|
||||
auto match = re.match(dirName);
|
||||
if (match.hasMatch()) {
|
||||
qDebug() << " Got match";
|
||||
auto pid = match.capturedRef("pid").toLongLong();
|
||||
auto timestamp = match.capturedRef("timestamp");
|
||||
qDebug() << " Is " << pid << " running?" << processIsRunning(pid);
|
||||
if (!processIsRunning(pid)) {
|
||||
qDebug() << " Removing: " << absoluteDirPath;
|
||||
qDebug() << " Removing old temporary directory: " << absoluteDirPath;
|
||||
absoluteDirPath.removeRecursively();
|
||||
removed++;
|
||||
} else {
|
||||
qDebug() << " Not removing (process is running): " << dir.absoluteDir();
|
||||
}
|
||||
} else {
|
||||
qDebug() << " NO MATCH";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ extern "C" FILE * __cdecl __iob_func(void) {
|
|||
|
||||
#if defined(Q_OS_LINUX) || defined(__APPLE__)
|
||||
#include <signal.h>
|
||||
#include <cerrno>
|
||||
#endif
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
@ -1094,7 +1095,12 @@ bool processIsRunning(int64_t pid) {
|
|||
}
|
||||
return false;
|
||||
#elif defined(Q_OS_LINUX) || defined(__APPLE__)
|
||||
return kill(pid, 0) != ESRCH;
|
||||
if (kill(pid, 0) == -1) {
|
||||
return errno != ESRCH;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
static_assert(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue