Fix more stuff. Detached tools, only MCEdit for now.

This commit is contained in:
Jan Dalheimer 2014-02-16 10:46:14 +01:00
parent 994972bf5d
commit 616c372690
17 changed files with 307 additions and 44 deletions

View File

@ -499,7 +499,11 @@ logic/assets/AssetsMigrateTask.cpp
logic/assets/AssetsUtils.h logic/assets/AssetsUtils.h
logic/assets/AssetsUtils.cpp logic/assets/AssetsUtils.cpp
# Profiling # Profiling and tools
logic/BaseExternalTool.h
logic/BaseExternalTool.cpp
logic/MCEditTool.h
logic/MCEditTool.cpp
logic/profiler/BaseProfiler.h logic/profiler/BaseProfiler.h
logic/profiler/BaseProfiler.cpp logic/profiler/BaseProfiler.cpp
logic/profiler/JProfiler.h logic/profiler/JProfiler.h

View File

@ -33,6 +33,7 @@
#include "logic/profiler/JProfiler.h" #include "logic/profiler/JProfiler.h"
#include "logic/profiler/JVisualVM.h" #include "logic/profiler/JVisualVM.h"
#include "logic/MCEditTool.h"
#include "pathutils.h" #include "pathutils.h"
#include "cmdutils.h" #include "cmdutils.h"
@ -223,6 +224,12 @@ MultiMC::MultiMC(int &argc, char **argv, bool root_override)
{ {
profiler->registerSettings(m_settings.get()); profiler->registerSettings(m_settings.get());
} }
m_tools.insert("mcedit",
std::shared_ptr<BaseDetachedToolFactory>(new MCEditFactory()));
for (auto tool : m_tools.values())
{
tool->registerSettings(m_settings.get());
}
// launch instance, if that's what should be done // launch instance, if that's what should be done
// WARNING: disabled until further notice // WARNING: disabled until further notice

View File

@ -23,6 +23,7 @@ class NotificationChecker;
class NewsChecker; class NewsChecker;
class StatusChecker; class StatusChecker;
class BaseProfilerFactory; class BaseProfilerFactory;
class BaseDetachedToolFactory;
#if defined(MMC) #if defined(MMC)
#undef MMC #undef MMC
@ -132,6 +133,10 @@ public:
{ {
return m_profilers; return m_profilers;
} }
QMap<QString, std::shared_ptr<BaseDetachedToolFactory>> tools()
{
return m_tools;
}
void installUpdates(const QString updateFilesDir, UpdateFlags flags = None); void installUpdates(const QString updateFilesDir, UpdateFlags flags = None);
@ -205,6 +210,7 @@ private:
std::shared_ptr<MinecraftVersionList> m_minecraftlist; std::shared_ptr<MinecraftVersionList> m_minecraftlist;
std::shared_ptr<JavaVersionList> m_javalist; std::shared_ptr<JavaVersionList> m_javalist;
QMap<QString, std::shared_ptr<BaseProfilerFactory>> m_profilers; QMap<QString, std::shared_ptr<BaseProfilerFactory>> m_profilers;
QMap<QString, std::shared_ptr<BaseDetachedToolFactory>> m_tools;
QsLogging::DestinationPtr m_fileDestination; QsLogging::DestinationPtr m_fileDestination;
QsLogging::DestinationPtr m_debugDestination; QsLogging::DestinationPtr m_debugDestination;

View File

@ -1440,8 +1440,35 @@ void MainWindow::instanceChanged(const QModelIndex &current, const QModelIndex &
for (auto profiler : MMC->profilers().values()) for (auto profiler : MMC->profilers().values())
{ {
QAction *profilerAction = launchMenu->addAction(profiler->name()); QAction *profilerAction = launchMenu->addAction(profiler->name());
QString error;
if (!profiler->check(&error))
{
profilerAction->setDisabled(true);
profilerAction->setToolTip(tr("Profiler not setup correctly. Go into settings, \"External Tools\"."));
}
else
{
connect(profilerAction, &QAction::triggered, [this, profiler](){doLaunch(true, profiler.get());}); connect(profilerAction, &QAction::triggered, [this, profiler](){doLaunch(true, profiler.get());});
} }
}
launchMenu->addSeparator()->setText(tr("Tools"));
for (auto tool : MMC->tools().values())
{
QAction *toolAction = launchMenu->addAction(tool->name());
QString error;
if (!tool->check(&error))
{
toolAction->setDisabled(true);
toolAction->setToolTip(tr("Tool not setup correctly. Go into settings, \"External Tools\"."));
}
else
{
connect(toolAction, &QAction::triggered, [this, tool]()
{
tool->createDetachedTool(m_selectedInstance, this)->run();
});
}
}
ui->actionLaunchInstance->setMenu(launchMenu); ui->actionLaunchInstance->setMenu(launchMenu);
MMC->settings()->set("SelectedInstance", m_selectedInstance->id()); MMC->settings()->set("SelectedInstance", m_selectedInstance->id());

View File

@ -374,6 +374,7 @@ void SettingsDialog::applySettings(SettingsObject *s)
// Profilers // Profilers
s->set("JProfilerPath", ui->jprofilerPathEdit->text()); s->set("JProfilerPath", ui->jprofilerPathEdit->text());
s->set("JVisualVMPath", ui->jvisualvmPathEdit->text()); s->set("JVisualVMPath", ui->jvisualvmPathEdit->text());
s->set("MCEditPath", ui->mceditPathEdit->text());
} }
void SettingsDialog::loadSettings(SettingsObject *s) void SettingsDialog::loadSettings(SettingsObject *s)
@ -457,6 +458,7 @@ void SettingsDialog::loadSettings(SettingsObject *s)
// Profilers // Profilers
ui->jprofilerPathEdit->setText(s->get("JProfilerPath").toString()); ui->jprofilerPathEdit->setText(s->get("JProfilerPath").toString());
ui->jvisualvmPathEdit->setText(s->get("JVisualVMPath").toString()); ui->jvisualvmPathEdit->setText(s->get("JVisualVMPath").toString());
ui->mceditPathEdit->setText(s->get("MCEditPath").toString());
} }
void SettingsDialog::on_javaDetectBtn_clicked() void SettingsDialog::on_javaDetectBtn_clicked()
@ -565,3 +567,29 @@ void SettingsDialog::on_jvisualvmCheckBtn_clicked()
QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK")); QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK"));
} }
} }
void SettingsDialog::on_mceditPathBtn_clicked()
{
QString raw_dir = QFileDialog::getOpenFileName(this, tr("MCEdit Path"),
ui->jvisualvmPathEdit->text());
QString cooked_dir = NormalizePath(raw_dir);
// do not allow current dir - it's dirty. Do not allow dirs that don't exist
if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists())
{
ui->mceditPathEdit->setText(cooked_dir);
}
}
void SettingsDialog::on_mceditCheckBtn_clicked()
{
QString error;
if (!MMC->tools()["mcedit"]->check(ui->mceditPathEdit->text(), &error))
{
QMessageBox::critical(this, tr("Error"),
tr("Error while checking MCEdit install:\n%1").arg(error));
}
else
{
QMessageBox::information(this, tr("OK"), tr("MCEdit setup seems to be OK"));
}
}

View File

@ -79,6 +79,8 @@ slots:
void on_jprofilerCheckBtn_clicked(); void on_jprofilerCheckBtn_clicked();
void on_jvisualvmPathBtn_clicked(); void on_jvisualvmPathBtn_clicked();
void on_jvisualvmCheckBtn_clicked(); void on_jvisualvmCheckBtn_clicked();
void on_mceditPathBtn_clicked();
void on_mceditCheckBtn_clicked();
/*! /*!
* Updates the list of update channels in the combo box. * Updates the list of update channels in the combo box.

View File

@ -863,9 +863,9 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="profilingTab"> <widget class="QWidget" name="externalToolsTab">
<attribute name="title"> <attribute name="title">
<string>Profiling</string> <string>External Tools</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_13"> <layout class="QVBoxLayout" name="verticalLayout_13">
<item> <item>
@ -928,6 +928,36 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>MCEdit</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLineEdit" name="mceditPathEdit"/>
</item>
<item>
<widget class="QPushButton" name="mceditPathBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="mceditCheckBtn">
<property name="text">
<string>Check</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer_3"> <spacer name="verticalSpacer_3">
<property name="orientation"> <property name="orientation">

View File

@ -0,0 +1,47 @@
#include "BaseExternalTool.h"
#include <QProcess>
#ifdef Q_OS_WIN
#include <windows.h>
#endif
BaseExternalTool::BaseExternalTool(BaseInstance *instance, QObject *parent)
: QObject(parent), m_instance(instance)
{
}
BaseExternalTool::~BaseExternalTool()
{
}
qint64 BaseExternalTool::pid(QProcess *process)
{
#ifdef Q_OS_WIN
struct _PROCESS_INFORMATION *procinfo = process->pid();
return procinfo->dwProcessId;
#else
return process->pid();
#endif
}
BaseDetachedTool::BaseDetachedTool(BaseInstance *instance, QObject *parent)
: BaseExternalTool(instance, parent)
{
}
void BaseDetachedTool::run()
{
runImpl();
}
BaseExternalToolFactory::~BaseExternalToolFactory()
{
}
BaseDetachedTool *BaseDetachedToolFactory::createDetachedTool(BaseInstance *instance, QObject *parent)
{
return qobject_cast<BaseDetachedTool *>(createTool(instance, parent));
}

56
logic/BaseExternalTool.h Normal file
View File

@ -0,0 +1,56 @@
#pragma once
#include <QObject>
class BaseInstance;
class SettingsObject;
class MinecraftProcess;
class QProcess;
class BaseExternalTool : public QObject
{
Q_OBJECT
public:
explicit BaseExternalTool(BaseInstance *instance, QObject *parent = 0);
virtual ~BaseExternalTool();
protected:
BaseInstance *m_instance;
qint64 pid(QProcess *process);
};
class BaseDetachedTool : public BaseExternalTool
{
Q_OBJECT
public:
explicit BaseDetachedTool(BaseInstance *instance, QObject *parent = 0);
public
slots:
void run();
protected:
virtual void runImpl() = 0;
};
class BaseExternalToolFactory
{
public:
virtual ~BaseExternalToolFactory();
virtual QString name() const = 0;
virtual void registerSettings(SettingsObject *settings) = 0;
virtual BaseExternalTool *createTool(BaseInstance *instance, QObject *parent = 0) = 0;
virtual bool check(QString *error) = 0;
virtual bool check(const QString &path, QString *error) = 0;
};
class BaseDetachedToolFactory : public BaseExternalToolFactory
{
public:
virtual BaseDetachedTool *createDetachedTool(BaseInstance *instance, QObject *parent = 0);
};

62
logic/MCEditTool.cpp Normal file
View File

@ -0,0 +1,62 @@
#include "MCEditTool.h"
#include <QDir>
#include <QProcess>
#include <QFileDialog>
#include "settingsobject.h"
#include "logic/BaseInstance.h"
#include "MultiMC.h"
MCEditTool::MCEditTool(BaseInstance *instance, QObject *parent)
: BaseDetachedTool(instance, parent)
{
}
void MCEditTool::runImpl()
{
const QString mceditPath = MMC->settings()->get("MCEditPath").toString();
const QString save = QFileDialog::getExistingDirectory(
MMC->activeWindow(), tr("MCEdit"),
QDir(m_instance->minecraftRoot()).absoluteFilePath("saves"));
if (save.isEmpty())
{
return;
}
const QString program =
QDir(mceditPath).absoluteFilePath("mcedit.py");
QProcess::startDetached(program, QStringList() << save, mceditPath);
}
void MCEditFactory::registerSettings(SettingsObject *settings)
{
settings->registerSetting("MCEditPath");
}
BaseExternalTool *MCEditFactory::createTool(BaseInstance *instance, QObject *parent)
{
return new MCEditTool(instance, parent);
}
bool MCEditFactory::check(QString *error)
{
return check(MMC->settings()->get("MCEditPath").toString(), error);
}
bool MCEditFactory::check(const QString &path, QString *error)
{
if (path.isEmpty())
{
*error = QObject::tr("Path is empty");
return false;
}
const QDir dir(path);
if (!dir.exists())
{
*error = QObject::tr("Path does not exist");
return false;
}
if (!dir.exists("mcedit.py"))
{
*error = QObject::tr("Path does not contain mcedit.py");
return false;
}
return true;
}

23
logic/MCEditTool.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include "BaseExternalTool.h"
class MCEditTool : public BaseDetachedTool
{
Q_OBJECT
public:
explicit MCEditTool(BaseInstance *instance, QObject *parent = 0);
protected:
void runImpl() override;
};
class MCEditFactory : public BaseDetachedToolFactory
{
public:
QString name() const override { return "MCEdit"; }
void registerSettings(SettingsObject *settings) override;
BaseExternalTool *createTool(BaseInstance *instance, QObject *parent = 0) override;
bool check(QString *error) override;
bool check(const QString &path, QString *error) override;
};

View File

@ -1,16 +1,9 @@
#include "BaseProfiler.h" #include "BaseProfiler.h"
#include <QProcess> #include <QProcess>
#ifdef Q_OS_WIN
#include <windows.h>
#endif
BaseProfiler::BaseProfiler(BaseInstance *instance, QObject *parent) BaseProfiler::BaseProfiler(BaseInstance *instance, QObject *parent)
: QObject(parent), m_instance(instance) : BaseExternalTool(instance, parent)
{
}
BaseProfiler::~BaseProfiler()
{ {
} }
@ -36,16 +29,7 @@ void BaseProfiler::abortProfilingImpl()
emit abortLaunch(tr("Profiler aborted")); emit abortLaunch(tr("Profiler aborted"));
} }
qint64 BaseProfiler::pid(QProcess *process) BaseProfiler *BaseProfilerFactory::createProfiler(BaseInstance *instance, QObject *parent)
{
#ifdef Q_OS_WIN
struct _PROCESS_INFORMATION *procinfo = process->pid();
return procinfo->dwProcessId;
#else
return process->pid();
#endif
}
BaseProfilerFactory::~BaseProfilerFactory()
{ {
return qobject_cast<BaseProfiler *>(createTool(instance, parent));
} }

View File

@ -1,18 +1,17 @@
#pragma once #pragma once
#include <QObject> #include "logic/BaseExternalTool.h"
class BaseInstance; class BaseInstance;
class SettingsObject; class SettingsObject;
class MinecraftProcess; class MinecraftProcess;
class QProcess; class QProcess;
class BaseProfiler : public QObject class BaseProfiler : public BaseExternalTool
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit BaseProfiler(BaseInstance *instance, QObject *parent = 0); explicit BaseProfiler(BaseInstance *instance, QObject *parent = 0);
virtual ~BaseProfiler();
public public
slots: slots:
@ -20,30 +19,18 @@ slots:
void abortProfiling(); void abortProfiling();
protected: protected:
BaseInstance *m_instance;
QProcess *m_profilerProcess; QProcess *m_profilerProcess;
virtual void beginProfilingImpl(MinecraftProcess *process) = 0; virtual void beginProfilingImpl(MinecraftProcess *process) = 0;
virtual void abortProfilingImpl(); virtual void abortProfilingImpl();
qint64 pid(QProcess *process);
signals: signals:
void readyToLaunch(const QString &message); void readyToLaunch(const QString &message);
void abortLaunch(const QString &message); void abortLaunch(const QString &message);
}; };
class BaseProfilerFactory class BaseProfilerFactory : public BaseExternalToolFactory
{ {
public: public:
virtual ~BaseProfilerFactory(); virtual BaseProfiler *createProfiler(BaseInstance *instance, QObject *parent = 0);
virtual QString name() const = 0;
virtual void registerSettings(SettingsObject *settings) = 0;
virtual BaseProfiler *createProfiler(BaseInstance *instance, QObject *parent = 0) = 0;
virtual bool check(QString *error) = 0;
virtual bool check(const QString &path, QString *error) = 0;
}; };

View File

@ -46,7 +46,7 @@ void JProfilerFactory::registerSettings(SettingsObject *settings)
settings->registerSetting("JProfilerPort", 42042); settings->registerSetting("JProfilerPort", 42042);
} }
BaseProfiler *JProfilerFactory::createProfiler(BaseInstance *instance, QObject *parent) BaseExternalTool *JProfilerFactory::createTool(BaseInstance *instance, QObject *parent)
{ {
return new JProfiler(instance, parent); return new JProfiler(instance, parent);
} }

View File

@ -17,7 +17,7 @@ class JProfilerFactory : public BaseProfilerFactory
public: public:
QString name() const override { return "JProfiler"; } QString name() const override { return "JProfiler"; }
void registerSettings(SettingsObject *settings) override; void registerSettings(SettingsObject *settings) override;
BaseProfiler *createProfiler(BaseInstance *instance, QObject *parent = 0) override; BaseExternalTool *createTool(BaseInstance *instance, QObject *parent = 0) override;
bool check(QString *error) override; bool check(QString *error) override;
bool check(const QString &path, QString *error) override; bool check(const QString &path, QString *error) override;
}; };

View File

@ -42,7 +42,7 @@ void JVisualVMFactory::registerSettings(SettingsObject *settings)
settings->registerSetting("JVisualVMPath"); settings->registerSetting("JVisualVMPath");
} }
BaseProfiler *JVisualVMFactory::createProfiler(BaseInstance *instance, QObject *parent) BaseExternalTool *JVisualVMFactory::createTool(BaseInstance *instance, QObject *parent)
{ {
return new JVisualVM(instance, parent); return new JVisualVM(instance, parent);
} }

View File

@ -17,7 +17,7 @@ class JVisualVMFactory : public BaseProfilerFactory
public: public:
QString name() const override { return "JVisualVM"; } QString name() const override { return "JVisualVM"; }
void registerSettings(SettingsObject *settings) override; void registerSettings(SettingsObject *settings) override;
BaseProfiler *createProfiler(BaseInstance *instance, QObject *parent = 0) override; BaseExternalTool *createTool(BaseInstance *instance, QObject *parent = 0) override;
bool check(QString *error) override; bool check(QString *error) override;
bool check(const QString &path, QString *error) override; bool check(const QString &path, QString *error) override;
}; };