summaryrefslogtreecommitdiffstats
path: root/api/logic/launch
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2016-11-03 01:10:16 +0100
committerPetr Mrázek <peterix@gmail.com>2016-11-03 01:11:57 +0100
commitf0b71f989ea798495ad80d1f059ae0a28514f9a2 (patch)
tree8551131b5ce3ccaa3c422f6635aefdbf6ca149ff /api/logic/launch
parentac66af6c13604a4eb2d36cc82417aa6753b84afe (diff)
downloadMultiMC-f0b71f989ea798495ad80d1f059ae0a28514f9a2.tar
MultiMC-f0b71f989ea798495ad80d1f059ae0a28514f9a2.tar.gz
MultiMC-f0b71f989ea798495ad80d1f059ae0a28514f9a2.tar.lz
MultiMC-f0b71f989ea798495ad80d1f059ae0a28514f9a2.tar.xz
MultiMC-f0b71f989ea798495ad80d1f059ae0a28514f9a2.zip
NOISSUE use LoggedProcess to work around issues with QProcess on macOS
Diffstat (limited to 'api/logic/launch')
-rw-r--r--api/logic/launch/LoggedProcess.cpp176
-rw-r--r--api/logic/launch/LoggedProcess.h79
-rw-r--r--api/logic/launch/MessageLevel.cpp36
-rw-r--r--api/logic/launch/MessageLevel.h28
-rw-r--r--api/logic/launch/steps/PostLaunchCommand.h2
-rw-r--r--api/logic/launch/steps/PreLaunchCommand.h4
-rw-r--r--api/logic/launch/steps/TextPrint.h2
-rw-r--r--api/logic/launch/steps/Update.h2
8 files changed, 5 insertions, 324 deletions
diff --git a/api/logic/launch/LoggedProcess.cpp b/api/logic/launch/LoggedProcess.cpp
deleted file mode 100644
index f89b4acc..00000000
--- a/api/logic/launch/LoggedProcess.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-#include "LoggedProcess.h"
-#include "MessageLevel.h"
-#include <QDebug>
-
-LoggedProcess::LoggedProcess(QObject *parent) : QProcess(parent)
-{
- // QProcess has a strange interface... let's map a lot of those into a few.
- connect(this, &QProcess::readyReadStandardOutput, this, &LoggedProcess::on_stdOut);
- connect(this, &QProcess::readyReadStandardError, this, &LoggedProcess::on_stdErr);
- connect(this, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(on_exit(int,QProcess::ExitStatus)));
- connect(this, SIGNAL(error(QProcess::ProcessError)), this, SLOT(on_error(QProcess::ProcessError)));
- connect(this, &QProcess::stateChanged, this, &LoggedProcess::on_stateChange);
-}
-
-LoggedProcess::~LoggedProcess()
-{
- if(m_is_detachable)
- {
- setProcessState(QProcess::NotRunning);
- }
-}
-
-QStringList reprocess(const QByteArray & data, QString & leftover)
-{
- QString str = leftover + QString::fromLocal8Bit(data);
-
- str.remove('\r');
- QStringList lines = str.split("\n");
- leftover = lines.takeLast();
- return lines;
-}
-
-void LoggedProcess::on_stdErr()
-{
- auto lines = reprocess(readAllStandardError(), m_err_leftover);
- emit log(lines, MessageLevel::StdErr);
-}
-
-void LoggedProcess::on_stdOut()
-{
- auto lines = reprocess(readAllStandardOutput(), m_out_leftover);
- emit log(lines, MessageLevel::StdOut);
-}
-
-void LoggedProcess::on_exit(int exit_code, QProcess::ExitStatus status)
-{
- // save the exit code
- m_exit_code = exit_code;
-
- // Flush console window
- if (!m_err_leftover.isEmpty())
- {
- emit log({m_err_leftover}, MessageLevel::StdErr);
- m_err_leftover.clear();
- }
- if (!m_out_leftover.isEmpty())
- {
- emit log({m_err_leftover}, MessageLevel::StdOut);
- m_out_leftover.clear();
- }
-
- // based on state, send signals
- if (!m_is_aborting)
- {
- if (status == QProcess::NormalExit)
- {
- //: Message displayed on instance exit
- emit log({tr("Process exited with code %1.").arg(exit_code)}, MessageLevel::MultiMC);
- changeState(LoggedProcess::Finished);
- }
- else
- {
- //: Message displayed on instance crashed
- if(exit_code == -1)
- emit log({tr("Process crashed.")}, MessageLevel::MultiMC);
- else
- emit log({tr("Process crashed with exitcode %1.").arg(exit_code)}, MessageLevel::MultiMC);
- changeState(LoggedProcess::Crashed);
- }
- }
- else
- {
- //: Message displayed after the instance exits due to kill request
- emit log({tr("Process was killed by user.")}, MessageLevel::Error);
- changeState(LoggedProcess::Aborted);
- }
-}
-
-void LoggedProcess::on_error(QProcess::ProcessError error)
-{
- switch(error)
- {
- case QProcess::FailedToStart:
- {
- emit log({tr("The process failed to start.")}, MessageLevel::Fatal);
- changeState(LoggedProcess::FailedToStart);
- break;
- }
- // we'll just ignore those... never needed them
- case QProcess::Crashed:
- case QProcess::ReadError:
- case QProcess::Timedout:
- case QProcess::UnknownError:
- case QProcess::WriteError:
- break;
- }
-}
-
-void LoggedProcess::kill()
-{
- m_is_aborting = true;
- QProcess::kill();
-}
-
-int LoggedProcess::exitCode() const
-{
- return m_exit_code;
-}
-
-void LoggedProcess::changeState(LoggedProcess::State state)
-{
- if(state == m_state)
- return;
- m_state = state;
- emit stateChanged(m_state);
-}
-
-LoggedProcess::State LoggedProcess::state() const
-{
- return m_state;
-}
-
-void LoggedProcess::on_stateChange(QProcess::ProcessState state)
-{
- switch(state)
- {
- case QProcess::NotRunning:
- break; // let's not - there are too many that handle this already.
- case QProcess::Starting:
- {
- if(m_state != LoggedProcess::NotRunning)
- {
- qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Starting;
- }
- changeState(LoggedProcess::Starting);
- return;
- }
- case QProcess::Running:
- {
- if(m_state != LoggedProcess::Starting)
- {
- qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Running;
- }
- changeState(LoggedProcess::Running);
- return;
- }
- }
-}
-
-#if defined Q_OS_WIN32
-#include <windows.h>
-#endif
-
-qint64 LoggedProcess::processId() const
-{
-#ifdef Q_OS_WIN
- return pid() ? pid()->dwProcessId : 0;
-#else
- return pid();
-#endif
-}
-
-void LoggedProcess::setDetachable(bool detachable)
-{
- m_is_detachable = detachable;
-}
diff --git a/api/logic/launch/LoggedProcess.h b/api/logic/launch/LoggedProcess.h
deleted file mode 100644
index c4e5c52c..00000000
--- a/api/logic/launch/LoggedProcess.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QProcess>
-#include "MessageLevel.h"
-
-/*
- * This is a basic process.
- * It has line-based logging support and hides some of the nasty bits.
- */
-class LoggedProcess : public QProcess
-{
-Q_OBJECT
-public:
- enum State
- {
- NotRunning,
- Starting,
- FailedToStart,
- Running,
- Finished,
- Crashed,
- Aborted
- };
-
-public:
- explicit LoggedProcess(QObject* parent = 0);
- virtual ~LoggedProcess();
-
- State state() const;
- int exitCode() const;
- qint64 processId() const;
-
- void setDetachable(bool detachable);
-
-signals:
- void log(QStringList lines, MessageLevel::Enum level);
- void stateChanged(LoggedProcess::State state);
-
-public slots:
- /**
- * @brief kill the process - equivalent to kill -9
- */
- void kill();
-
-
-private slots:
- void on_stdErr();
- void on_stdOut();
- void on_exit(int exit_code, QProcess::ExitStatus status);
- void on_error(QProcess::ProcessError error);
- void on_stateChange(QProcess::ProcessState);
-
-private:
- void changeState(LoggedProcess::State state);
-
-private:
- QString m_err_leftover;
- QString m_out_leftover;
- bool m_killed = false;
- State m_state = NotRunning;
- int m_exit_code = 0;
- bool m_is_aborting = false;
- bool m_is_detachable = false;
-};
diff --git a/api/logic/launch/MessageLevel.cpp b/api/logic/launch/MessageLevel.cpp
deleted file mode 100644
index a5191290..00000000
--- a/api/logic/launch/MessageLevel.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "MessageLevel.h"
-
-MessageLevel::Enum MessageLevel::getLevel(const QString& levelName)
-{
- if (levelName == "MultiMC")
- return MessageLevel::MultiMC;
- else if (levelName == "Debug")
- return MessageLevel::Debug;
- else if (levelName == "Info")
- return MessageLevel::Info;
- else if (levelName == "Message")
- return MessageLevel::Message;
- else if (levelName == "Warning")
- return MessageLevel::Warning;
- else if (levelName == "Error")
- return MessageLevel::Error;
- else if (levelName == "Fatal")
- return MessageLevel::Fatal;
- // Skip PrePost, it's not exposed to !![]!
- // Also skip StdErr and StdOut
- else
- return MessageLevel::Unknown;
-}
-
-MessageLevel::Enum MessageLevel::fromLine(QString &line)
-{
- // Level prefix
- int endmark = line.indexOf("]!");
- if (line.startsWith("!![") && endmark != -1)
- {
- auto level = MessageLevel::getLevel(line.left(endmark).mid(3));
- line = line.mid(endmark + 2);
- return level;
- }
- return MessageLevel::Unknown;
-}
diff --git a/api/logic/launch/MessageLevel.h b/api/logic/launch/MessageLevel.h
deleted file mode 100644
index 0128148d..00000000
--- a/api/logic/launch/MessageLevel.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-
-#include <QString>
-
-/**
- * @brief the MessageLevel Enum
- * defines what level a log message is
- */
-namespace MessageLevel
-{
-enum Enum
-{
- Unknown, /**< No idea what this is or where it came from */
- StdOut, /**< Undetermined stderr messages */
- StdErr, /**< Undetermined stdout messages */
- MultiMC, /**< MultiMC Messages */
- Debug, /**< Debug Messages */
- Info, /**< Info Messages */
- Message, /**< Standard Messages */
- Warning, /**< Warnings */
- Error, /**< Errors */
- Fatal, /**< Fatal Errors */
-};
-MessageLevel::Enum getLevel(const QString &levelName);
-
-/* Get message level from a line. Line is modified if it was successful. */
-MessageLevel::Enum fromLine(QString &line);
-}
diff --git a/api/logic/launch/steps/PostLaunchCommand.h b/api/logic/launch/steps/PostLaunchCommand.h
index 4d5b0a52..2b68ee86 100644
--- a/api/logic/launch/steps/PostLaunchCommand.h
+++ b/api/logic/launch/steps/PostLaunchCommand.h
@@ -16,7 +16,7 @@
#pragma once
#include <launch/LaunchStep.h>
-#include <launch/LoggedProcess.h>
+#include <LoggedProcess.h>
class PostLaunchCommand: public LaunchStep
{
diff --git a/api/logic/launch/steps/PreLaunchCommand.h b/api/logic/launch/steps/PreLaunchCommand.h
index 077bdfca..eb7bc0b6 100644
--- a/api/logic/launch/steps/PreLaunchCommand.h
+++ b/api/logic/launch/steps/PreLaunchCommand.h
@@ -15,8 +15,8 @@
#pragma once
-#include <launch/LaunchStep.h>
-#include <launch/LoggedProcess.h>
+#include "launch/LaunchStep.h"
+#include "LoggedProcess.h"
class PreLaunchCommand: public LaunchStep
{
diff --git a/api/logic/launch/steps/TextPrint.h b/api/logic/launch/steps/TextPrint.h
index fdd9014a..5b82aff8 100644
--- a/api/logic/launch/steps/TextPrint.h
+++ b/api/logic/launch/steps/TextPrint.h
@@ -16,7 +16,7 @@
#pragma once
#include <launch/LaunchStep.h>
-#include <launch/LoggedProcess.h>
+#include <LoggedProcess.h>
#include <java/JavaChecker.h>
#include "multimc_logic_export.h"
diff --git a/api/logic/launch/steps/Update.h b/api/logic/launch/steps/Update.h
index 1739de47..ad7cfa69 100644
--- a/api/logic/launch/steps/Update.h
+++ b/api/logic/launch/steps/Update.h
@@ -17,7 +17,7 @@
#include <launch/LaunchStep.h>
#include <QObjectPtr.h>
-#include <launch/LoggedProcess.h>
+#include <LoggedProcess.h>
#include <java/JavaChecker.h>
// FIXME: stupid. should be defined by the instance type? or even completely abstracted away...