NOISSUE Flatten gui and logic libraries into MultiMC

This commit is contained in:
Petr Mrázek
2021-07-25 19:11:59 +02:00
parent dd13368085
commit 20b9f2b42a
1113 changed files with 1228 additions and 1401 deletions

View File

@ -0,0 +1,55 @@
#include "SequentialTask.h"
SequentialTask::SequentialTask(QObject *parent) : Task(parent), m_currentIndex(-1)
{
}
void SequentialTask::addTask(std::shared_ptr<Task> task)
{
m_queue.append(task);
}
void SequentialTask::executeTask()
{
m_currentIndex = -1;
startNext();
}
void SequentialTask::startNext()
{
if (m_currentIndex != -1)
{
std::shared_ptr<Task> previous = m_queue[m_currentIndex];
disconnect(previous.get(), 0, this, 0);
}
m_currentIndex++;
if (m_queue.isEmpty() || m_currentIndex >= m_queue.size())
{
emitSucceeded();
return;
}
std::shared_ptr<Task> next = m_queue[m_currentIndex];
connect(next.get(), SIGNAL(failed(QString)), this, SLOT(subTaskFailed(QString)));
connect(next.get(), SIGNAL(status(QString)), this, SLOT(subTaskStatus(QString)));
connect(next.get(), SIGNAL(progress(qint64, qint64)), this, SLOT(subTaskProgress(qint64, qint64)));
connect(next.get(), SIGNAL(succeeded()), this, SLOT(startNext()));
next->start();
}
void SequentialTask::subTaskFailed(const QString &msg)
{
emitFailed(msg);
}
void SequentialTask::subTaskStatus(const QString &msg)
{
setStatus(msg);
}
void SequentialTask::subTaskProgress(qint64 current, qint64 total)
{
if(total == 0)
{
setProgress(0, 100);
return;
}
setProgress(current, total);
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "Task.h"
#include <QQueue>
#include <memory>
class SequentialTask : public Task
{
Q_OBJECT
public:
explicit SequentialTask(QObject *parent = 0);
virtual ~SequentialTask() {};
void addTask(std::shared_ptr<Task> task);
protected:
void executeTask();
private
slots:
void startNext();
void subTaskFailed(const QString &msg);
void subTaskStatus(const QString &msg);
void subTaskProgress(qint64 current, qint64 total);
private:
QQueue<std::shared_ptr<Task> > m_queue;
int m_currentIndex;
};

168
launcher/tasks/Task.cpp Normal file
View File

@ -0,0 +1,168 @@
/* Copyright 2013-2021 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.
*/
#include "Task.h"
#include <QDebug>
Task::Task(QObject *parent) : QObject(parent)
{
}
void Task::setStatus(const QString &new_status)
{
if(m_status != new_status)
{
m_status = new_status;
emit status(m_status);
}
}
void Task::setProgress(qint64 current, qint64 total)
{
m_progress = current;
m_progressTotal = total;
emit progress(m_progress, m_progressTotal);
}
void Task::start()
{
switch(m_state)
{
case State::Inactive:
{
qDebug() << "Task" << describe() << "starting for the first time";
break;
}
case State::AbortedByUser:
{
qDebug() << "Task" << describe() << "restarting for after being aborted by user";
break;
}
case State::Failed:
{
qDebug() << "Task" << describe() << "restarting for after failing at first";
break;
}
case State::Succeeded:
{
qDebug() << "Task" << describe() << "restarting for after succeeding at first";
break;
}
case State::Running:
{
qWarning() << "MultiMC tried to start task" << describe() << "while it was already running!";
return;
}
}
// NOTE: only fall thorugh to here in end states
m_state = State::Running;
emit started();
executeTask();
}
void Task::emitFailed(QString reason)
{
// Don't fail twice.
if (!isRunning())
{
qCritical() << "Task" << describe() << "failed while not running!!!!: " << reason;
return;
}
m_state = State::Failed;
m_failReason = reason;
qCritical() << "Task" << describe() << "failed: " << reason;
emit failed(reason);
emit finished();
}
void Task::emitAborted()
{
// Don't abort twice.
if (!isRunning())
{
qCritical() << "Task" << describe() << "aborted while not running!!!!";
return;
}
m_state = State::AbortedByUser;
m_failReason = "Aborted.";
qDebug() << "Task" << describe() << "aborted.";
emit failed(m_failReason);
emit finished();
}
void Task::emitSucceeded()
{
// Don't succeed twice.
if (!isRunning())
{
qCritical() << "Task" << describe() << "succeeded while not running!!!!";
return;
}
m_state = State::Succeeded;
qDebug() << "Task" << describe() << "succeeded";
emit succeeded();
emit finished();
}
QString Task::describe()
{
QString outStr;
QTextStream out(&outStr);
out << metaObject()->className() << QChar('(');
auto name = objectName();
if(name.isEmpty())
{
out << QString("0x%1").arg((quintptr)this, 0, 16);
}
else
{
out << name;
}
out << QChar(')');
out.flush();
return outStr;
}
bool Task::isRunning() const
{
return m_state == State::Running;
}
bool Task::isFinished() const
{
return m_state != State::Running && m_state != State::Inactive;
}
bool Task::wasSuccessful() const
{
return m_state == State::Succeeded;
}
QString Task::failReason() const
{
return m_failReason;
}
void Task::logWarning(const QString& line)
{
qWarning() << line;
m_Warnings.append(line);
}
QStringList Task::warnings() const
{
return m_Warnings;
}

106
launcher/tasks/Task.h Normal file
View File

@ -0,0 +1,106 @@
/* Copyright 2013-2021 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 <QObject>
#include <QString>
#include <QStringList>
class Task : public QObject
{
Q_OBJECT
public:
enum class State
{
Inactive,
Running,
Succeeded,
Failed,
AbortedByUser
};
public:
explicit Task(QObject *parent = 0);
virtual ~Task() {};
bool isRunning() const;
bool isFinished() const;
bool wasSuccessful() const;
/*!
* Returns the string that was passed to emitFailed as the error message when the task failed.
* If the task hasn't failed, returns an empty string.
*/
QString failReason() const;
virtual QStringList warnings() const;
virtual bool canAbort() const { return false; }
QString getStatus()
{
return m_status;
}
qint64 getProgress()
{
return m_progress;
}
qint64 getTotalProgress()
{
return m_progressTotal;
}
protected:
void logWarning(const QString & line);
private:
QString describe();
signals:
void started();
void progress(qint64 current, qint64 total);
void finished();
void succeeded();
void failed(QString reason);
void status(QString status);
public slots:
virtual void start();
virtual bool abort() { return false; };
protected:
virtual void executeTask() = 0;
protected slots:
virtual void emitSucceeded();
virtual void emitAborted();
virtual void emitFailed(QString reason);
public slots:
void setStatus(const QString &status);
void setProgress(qint64 current, qint64 total);
private:
State m_state = State::Inactive;
QStringList m_Warnings;
QString m_failReason = "";
QString m_status;
int m_progress = 0;
int m_progressTotal = 100;
};