SCRATCH eliminate InstanceFactory

This commit is contained in:
Petr Mrázek
2015-02-01 03:08:25 +01:00
parent c088d3bef0
commit 154d19bb74
23 changed files with 205 additions and 303 deletions

View File

@ -29,11 +29,10 @@
#include "logic/minecraft/MinecraftVersionList.h"
#include "logic/icons/IconList.h"
BaseInstance::BaseInstance(const QString &rootDir, SettingsObject *settings, QObject *parent)
: QObject(parent)
BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: QObject()
{
m_settings = std::shared_ptr<SettingsObject>(settings);
m_settings = settings;
m_rootDir = rootDir;
m_settings->registerSetting("name", "Unnamed Instance");
@ -42,8 +41,6 @@ BaseInstance::BaseInstance(const QString &rootDir, SettingsObject *settings, QOb
m_settings->registerSetting("notes", "");
m_settings->registerSetting("lastLaunchTime", 0);
auto globalSettings = MMC->settings();
// Java Settings
m_settings->registerSetting("OverrideJava", false);
m_settings->registerSetting("OverrideJavaLocation", false);

View File

@ -51,7 +51,7 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
Q_OBJECT
protected:
/// no-touchy!
BaseInstance(const QString &rootDir, SettingsObject *settings, QObject *parent = 0);
BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
public:
/// virtual destructor to make sure the destruction is COMPLETE

View File

@ -1,135 +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.
*/
#include <QDir>
#include <QFileInfo>
#include "logic/settings/INIFile.h"
#include "logic/settings/INISettingsObject.h"
#include "logic/settings/Setting.h"
#include <pathutils.h>
#include "logger/QsLog.h"
#include "logic/InstanceFactory.h"
#include "logic/BaseInstance.h"
#include "logic/LegacyInstance.h"
#include "logic/OneSixInstance.h"
#include "logic/OneSixInstance.h"
#include "logic/BaseVersion.h"
#include "logic/minecraft/MinecraftVersion.h"
InstanceFactory InstanceFactory::loader;
InstanceFactory::InstanceFactory() : QObject(NULL)
{
}
InstanceFactory::InstLoadError InstanceFactory::loadInstance(InstancePtr &inst,
const QString &instDir)
{
auto m_settings = new INISettingsObject(PathCombine(instDir, "instance.cfg"));
m_settings->registerSetting("InstanceType", "Legacy");
QString inst_type = m_settings->get("InstanceType").toString();
// FIXME: replace with a map lookup, where instance classes register their types
if (inst_type == "OneSix" || inst_type == "Nostalgia")
{
inst.reset(new OneSixInstance(instDir, m_settings));
}
else if (inst_type == "Legacy")
{
inst.reset(new LegacyInstance(instDir, m_settings));
}
else
{
return InstanceFactory::UnknownLoadError;
}
inst->init();
return NoLoadError;
}
InstanceFactory::InstCreateError
InstanceFactory::createInstance(InstancePtr &inst, BaseVersionPtr version, const QString &instDir)
{
QDir rootDir(instDir);
QLOG_DEBUG() << instDir.toUtf8();
if (!rootDir.exists() && !rootDir.mkpath("."))
{
QLOG_ERROR() << "Can't create instance folder" << instDir;
return InstanceFactory::CantCreateDir;
}
if (!version)
{
QLOG_ERROR() << "Can't create instance for non-existing MC version";
return InstanceFactory::NoSuchVersion;
}
auto m_settings = new INISettingsObject(PathCombine(instDir, "instance.cfg"));
m_settings->registerSetting("InstanceType", "Legacy");
auto minecraftVersion = std::dynamic_pointer_cast<MinecraftVersion>(version);
if(minecraftVersion)
{
auto mcVer = std::dynamic_pointer_cast<MinecraftVersion>(version);
m_settings->set("InstanceType", "OneSix");
inst.reset(new OneSixInstance(instDir, m_settings));
inst->setIntendedVersionId(version->descriptor());
inst->init();
return InstanceFactory::NoCreateError;
}
delete m_settings;
return InstanceFactory::NoSuchVersion;
}
InstanceFactory::InstCreateError InstanceFactory::copyInstance(InstancePtr &newInstance,
InstancePtr &oldInstance,
const QString &instDir)
{
QDir rootDir(instDir);
QLOG_DEBUG() << instDir.toUtf8();
if (!copyPath(oldInstance->instanceRoot(), instDir))
{
rootDir.removeRecursively();
return InstanceFactory::CantCreateDir;
}
INISettingsObject settings_obj(PathCombine(instDir, "instance.cfg"));
settings_obj.registerSetting("InstanceType", "Legacy");
QString inst_type = settings_obj.get("InstanceType").toString();
oldInstance->copy(instDir);
auto error = loadInstance(newInstance, instDir);
switch (error)
{
case NoLoadError:
return NoCreateError;
case NotAnInstance:
rootDir.removeRecursively();
return CantCreateDir;
default:
case UnknownLoadError:
rootDir.removeRecursively();
return UnknownCreateError;
}
}

View File

@ -1,100 +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 <QObject>
#include <QMap>
#include <QList>
#include "BaseVersion.h"
#include "BaseInstance.h"
struct BaseVersion;
class BaseInstance;
/*!
* The \b InstanceFactory\b is a singleton that manages loading and creating instances.
*/
class InstanceFactory : public QObject
{
Q_OBJECT
public:
/*!
* \brief Gets a reference to the instance loader.
*/
static InstanceFactory &get()
{
return loader;
}
enum InstLoadError
{
NoLoadError = 0,
UnknownLoadError,
NotAnInstance
};
enum InstCreateError
{
NoCreateError = 0,
NoSuchVersion,
UnknownCreateError,
InstExists,
CantCreateDir
};
/*!
* \brief Creates a stub instance
*
* \param inst Pointer to store the created instance in.
* \param version Game version to use for the instance
* \param instDir The new instance's directory.
* \param type The type of instance to create
* \return An InstCreateError error code.
* - InstExists if the given instance directory is already an instance.
* - CantCreateDir if the given instance directory cannot be created.
*/
InstCreateError createInstance(InstancePtr &inst, BaseVersionPtr version,
const QString &instDir);
/*!
* \brief Creates a copy of an existing instance with a new name
*
* \param newInstance Pointer to store the created instance in.
* \param oldInstance The instance to copy
* \param instDir The new instance's directory.
* \return An InstCreateError error code.
* - InstExists if the given instance directory is already an instance.
* - CantCreateDir if the given instance directory cannot be created.
*/
InstCreateError copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance,
const QString &instDir);
/*!
* \brief Loads an instance from the given directory.
* Checks the instance's INI file to figure out what the instance's type is first.
* \param inst Pointer to store the loaded instance in.
* \param instDir The instance's directory.
* \return An InstLoadError error code.
* - NotAnInstance if the given instance directory isn't a valid instance.
*/
InstLoadError loadInstance(InstancePtr &inst, const QString &instDir);
private:
InstanceFactory();
static InstanceFactory loader;
};

View File

@ -31,18 +31,19 @@
#include "logic/icons/IconList.h"
#include "logic/minecraft/MinecraftVersionList.h"
#include "logic/BaseInstance.h"
#include "logic/InstanceFactory.h"
#include "ftb/FTBPlugin.h"
#include "logic/ftb/FTBPlugin.h"
#include "settings/INISettingsObject.h"
#include "OneSixInstance.h"
#include "LegacyInstance.h"
#include "logger/QsLog.h"
#include "gui/groupview/GroupView.h"
const static int GROUP_FILE_FORMAT_VERSION = 1;
InstanceList::InstanceList(const QString &instDir, QObject *parent)
InstanceList::InstanceList(SettingsObjectPtr globalSettings, const QString &instDir, QObject *parent)
: QAbstractListModel(parent), m_instDir(instDir)
{
connect(MMC, &MultiMC::aboutToQuit, this, &InstanceList::saveGroupList);
m_globalSettings = globalSettings;
if (!QDir::current().exists(m_instDir))
{
QDir::current().mkpath(m_instDir);
@ -301,7 +302,7 @@ InstanceList::InstListError InstanceList::loadList()
continue;
QLOG_INFO() << "Loading MultiMC instance from " << subDir;
InstancePtr instPtr;
auto error = InstanceFactory::get().loadInstance(instPtr, subDir);
auto error = loadInstance(instPtr, subDir);
if(!continueProcessInstance(instPtr, error, subDir, groupMap))
continue;
tempList.append(instPtr);
@ -399,7 +400,7 @@ int InstanceList::getInstIndex(BaseInstance *inst) const
bool InstanceList::continueProcessInstance(InstancePtr instPtr, const int error,
const QDir &dir, QMap<QString, QString> &groupMap)
{
if (error != InstanceFactory::NoLoadError && error != InstanceFactory::NotAnInstance)
if (error != InstanceList::NoLoadError && error != InstanceList::NotAnInstance)
{
QString errorMsg = QString("Failed to load instance %1: ")
.arg(QFileInfo(dir.absolutePath()).baseName())
@ -433,6 +434,100 @@ bool InstanceList::continueProcessInstance(InstancePtr instPtr, const int error,
}
}
InstanceList::InstLoadError
InstanceList::loadInstance(InstancePtr &inst, const QString &instDir)
{
auto instanceSettings = std::make_shared<INISettingsObject>(PathCombine(instDir, "instance.cfg"));
instanceSettings->registerSetting("InstanceType", "Legacy");
QString inst_type = instanceSettings->get("InstanceType").toString();
// FIXME: replace with a map lookup, where instance classes register their types
if (inst_type == "OneSix" || inst_type == "Nostalgia")
{
inst.reset(new OneSixInstance(m_globalSettings, instanceSettings, instDir));
}
else if (inst_type == "Legacy")
{
inst.reset(new LegacyInstance(m_globalSettings, instanceSettings, instDir));
}
else
{
return InstanceList::UnknownLoadError;
}
inst->init();
return NoLoadError;
}
InstanceList::InstCreateError
InstanceList::createInstance(InstancePtr &inst, BaseVersionPtr version, const QString &instDir)
{
QDir rootDir(instDir);
QLOG_DEBUG() << instDir.toUtf8();
if (!rootDir.exists() && !rootDir.mkpath("."))
{
QLOG_ERROR() << "Can't create instance folder" << instDir;
return InstanceList::CantCreateDir;
}
if (!version)
{
QLOG_ERROR() << "Can't create instance for non-existing MC version";
return InstanceList::NoSuchVersion;
}
auto instanceSettings = std::make_shared<INISettingsObject>(PathCombine(instDir, "instance.cfg"));
instanceSettings->registerSetting("InstanceType", "Legacy");
auto minecraftVersion = std::dynamic_pointer_cast<MinecraftVersion>(version);
if(minecraftVersion)
{
auto mcVer = std::dynamic_pointer_cast<MinecraftVersion>(version);
instanceSettings->set("InstanceType", "OneSix");
inst.reset(new OneSixInstance(m_globalSettings, instanceSettings, instDir));
inst->setIntendedVersionId(version->descriptor());
inst->init();
return InstanceList::NoCreateError;
}
return InstanceList::NoSuchVersion;
}
InstanceList::InstCreateError
InstanceList::copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance, const QString &instDir)
{
QDir rootDir(instDir);
QLOG_DEBUG() << instDir.toUtf8();
if (!copyPath(oldInstance->instanceRoot(), instDir))
{
rootDir.removeRecursively();
return InstanceList::CantCreateDir;
}
INISettingsObject settings_obj(PathCombine(instDir, "instance.cfg"));
settings_obj.registerSetting("InstanceType", "Legacy");
QString inst_type = settings_obj.get("InstanceType").toString();
oldInstance->copy(instDir);
auto error = loadInstance(newInstance, instDir);
switch (error)
{
case NoLoadError:
return NoCreateError;
case NotAnInstance:
rootDir.removeRecursively();
return CantCreateDir;
default:
case UnknownLoadError:
rootDir.removeRecursively();
return UnknownCreateError;
}
}
void InstanceList::instanceNuked(BaseInstance *inst)
{
int i = getInstIndex(inst);

View File

@ -23,7 +23,6 @@
#include "logic/BaseInstance.h"
class BaseInstance;
class QDir;
class InstanceList : public QAbstractListModel
@ -37,7 +36,7 @@ slots:
void saveGroupList();
public:
explicit InstanceList(const QString &instDir, QObject *parent = 0);
explicit InstanceList(SettingsObjectPtr globalSettings, const QString &instDir, QObject *parent = 0);
virtual ~InstanceList();
public:
@ -62,6 +61,22 @@ public:
UnknownError
};
enum InstLoadError
{
NoLoadError = 0,
UnknownLoadError,
NotAnInstance
};
enum InstCreateError
{
NoCreateError = 0,
NoSuchVersion,
UnknownCreateError,
InstExists,
CantCreateDir
};
QString instDir() const
{
return m_instDir;
@ -98,6 +113,43 @@ public:
// FIXME: instead of iterating through all instances and forming a set, keep the set around
QStringList getGroups();
/*!
* \brief Creates a stub instance
*
* \param inst Pointer to store the created instance in.
* \param version Game version to use for the instance
* \param instDir The new instance's directory.
* \return An InstCreateError error code.
* - InstExists if the given instance directory is already an instance.
* - CantCreateDir if the given instance directory cannot be created.
*/
InstCreateError createInstance(InstancePtr &inst, BaseVersionPtr version,
const QString &instDir);
/*!
* \brief Creates a copy of an existing instance with a new name
*
* \param newInstance Pointer to store the created instance in.
* \param oldInstance The instance to copy
* \param instDir The new instance's directory.
* \return An InstCreateError error code.
* - InstExists if the given instance directory is already an instance.
* - CantCreateDir if the given instance directory cannot be created.
*/
InstCreateError copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance,
const QString &instDir);
/*!
* \brief Loads an instance from the given directory.
* Checks the instance's INI file to figure out what the instance's type is first.
* \param inst Pointer to store the loaded instance in.
* \param instDir The instance's directory.
* \return An InstLoadError error code.
* - NotAnInstance if the given instance directory isn't a valid instance.
*/
InstLoadError loadInstance(InstancePtr &inst, const QString &instDir);
signals:
void dataIsInvalid();
@ -127,6 +179,7 @@ protected:
QString m_instDir;
QList<InstancePtr> m_instances;
QSet<QString> m_groups;
SettingsObjectPtr m_globalSettings;
};
class InstanceProxyModel : public GroupedProxyModel

View File

@ -35,8 +35,8 @@
#include <gui/pages/NotesPage.h>
#include <gui/pages/ScreenshotsPage.h>
LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings, QObject *parent)
: MinecraftInstance(rootDir, settings, parent)
LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: MinecraftInstance(globalSettings, settings, rootDir)
{
settings->registerSetting("NeedsRebuild", true);
settings->registerSetting("ShouldUpdate", false);

View File

@ -26,8 +26,7 @@ class LegacyInstance : public MinecraftInstance, public BasePageProvider
Q_OBJECT
public:
explicit LegacyInstance(const QString &rootDir, SettingsObject *settings,
QObject *parent = 0);
explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
virtual void init() {};

View File

@ -38,9 +38,8 @@
#include "gui/pages/NotesPage.h"
#include "gui/pages/ScreenshotsPage.h"
#include "gui/pages/OtherLogsPage.h"
OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings, QObject *parent)
: MinecraftInstance(rootDir, settings, parent)
OneSixInstance::OneSixInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: MinecraftInstance(globalSettings, settings, rootDir)
{
m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
}

View File

@ -25,8 +25,7 @@ class OneSixInstance : public MinecraftInstance, public BasePageProvider
{
Q_OBJECT
public:
explicit OneSixInstance(const QString &rootDir, SettingsObject *settings,
QObject *parent = 0);
explicit OneSixInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
virtual ~OneSixInstance(){};
virtual void init();

View File

@ -4,7 +4,6 @@
#include "OneSixFTBInstance.h"
#include <logic/BaseInstance.h>
#include <logic/icons/IconList.h>
#include <logic/InstanceFactory.h>
#include <logic/InstanceList.h>
#include <logic/minecraft/MinecraftVersionList.h>
#include <logic/settings/INISettingsObject.h>
@ -134,7 +133,7 @@ QSet<FTBRecord> discoverFTBInstances()
InstancePtr loadInstance(const QString &instDir)
{
auto m_settings = new INISettingsObject(PathCombine(instDir, "instance.cfg"));
auto m_settings = std::make_shared<INISettingsObject>(PathCombine(instDir, "instance.cfg"));
InstancePtr inst;
@ -144,11 +143,11 @@ InstancePtr loadInstance(const QString &instDir)
if (inst_type == "LegacyFTB")
{
inst.reset(new LegacyFTBInstance(instDir, m_settings));
inst.reset(new LegacyFTBInstance(MMC->settings(), m_settings, instDir));
}
else if (inst_type == "OneSixFTB")
{
inst.reset(new OneSixFTBInstance(instDir, m_settings));
inst.reset(new OneSixFTBInstance(MMC->settings(), m_settings, instDir));
}
inst->init();
return inst;
@ -173,19 +172,19 @@ InstancePtr createInstance(MinecraftVersionPtr version, const QString &instDir)
return nullptr;
}
auto m_settings = new INISettingsObject(PathCombine(instDir, "instance.cfg"));
auto m_settings = std::make_shared<INISettingsObject>(PathCombine(instDir, "instance.cfg"));
m_settings->registerSetting("InstanceType", "Legacy");
if (version->usesLegacyLauncher())
{
m_settings->set("InstanceType", "LegacyFTB");
inst.reset(new LegacyFTBInstance(instDir, m_settings));
inst.reset(new LegacyFTBInstance(MMC->settings(),m_settings, instDir));
inst->setIntendedVersionId(version->descriptor());
}
else
{
m_settings->set("InstanceType", "OneSixFTB");
inst.reset(new OneSixFTBInstance(instDir, m_settings));
inst.reset(new OneSixFTBInstance(MMC->settings(),m_settings, instDir));
inst->setIntendedVersionId(version->descriptor());
inst->init();
}
@ -239,7 +238,7 @@ void FTBPlugin::loadInstances(QMap<QString, QString> &groupMap, QList<InstancePt
instPtr->setIconKey(iconKey);
instPtr->setIntendedVersionId(record.mcVersion);
instPtr->setNotes(record.description);
if (!InstanceList::continueProcessInstance(instPtr, InstanceFactory::NoCreateError, record.instanceDir, groupMap))
if (!InstanceList::continueProcessInstance(instPtr, InstanceList::NoCreateError, record.instanceDir, groupMap))
continue;
tempList.append(InstancePtr(instPtr));
}
@ -259,7 +258,7 @@ void FTBPlugin::loadInstances(QMap<QString, QString> &groupMap, QList<InstancePt
instPtr->setIntendedVersionId(record.mcVersion);
}
instPtr->setNotes(record.description);
if (!InstanceList::continueProcessInstance(instPtr, InstanceFactory::NoCreateError, record.instanceDir, groupMap))
if (!InstanceList::continueProcessInstance(instPtr, InstanceList::NoCreateError, record.instanceDir, groupMap))
continue;
tempList.append(InstancePtr(instPtr));
}

View File

@ -2,8 +2,8 @@
#include <logic/settings/INISettingsObject.h>
#include <QDir>
LegacyFTBInstance::LegacyFTBInstance(const QString &rootDir, SettingsObject *settings, QObject *parent) :
LegacyInstance(rootDir, settings, parent)
LegacyFTBInstance::LegacyFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) :
LegacyInstance(globalSettings, settings, rootDir)
{
}

View File

@ -6,8 +6,7 @@ class LegacyFTBInstance : public LegacyInstance
{
Q_OBJECT
public:
explicit LegacyFTBInstance(const QString &rootDir, SettingsObject *settings,
QObject *parent = 0);
explicit LegacyFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
virtual QString getStatusbarDescription();
virtual QString id() const;
virtual void copy(const QDir &newDir);

View File

@ -11,8 +11,8 @@
#include "MultiMC.h"
#include "pathutils.h"
OneSixFTBInstance::OneSixFTBInstance(const QString &rootDir, SettingsObject *settings, QObject *parent) :
OneSixInstance(rootDir, settings, parent)
OneSixFTBInstance::OneSixFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) :
OneSixInstance(globalSettings, settings, rootDir)
{
}

View File

@ -8,8 +8,7 @@ class OneSixFTBInstance : public OneSixInstance
{
Q_OBJECT
public:
explicit OneSixFTBInstance(const QString &rootDir, SettingsObject *settings,
QObject *parent = 0);
explicit OneSixFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
virtual ~OneSixFTBInstance(){};
void copy(const QDir &newDir) override;

View File

@ -4,11 +4,9 @@
#include <pathutils.h>
#include "logic/minecraft/MinecraftVersionList.h"
MinecraftInstance::MinecraftInstance(const QString &rootDir, SettingsObject *settings, QObject *parent)
: BaseInstance(rootDir, settings, parent)
MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: BaseInstance(globalSettings, settings, rootDir)
{
auto globalSettings = MMC->settings();
// Java Settings
m_settings->registerSetting("OverrideJava", false);
m_settings->registerSetting("OverrideJavaLocation", false);

View File

@ -4,7 +4,7 @@
class MinecraftInstance: public BaseInstance
{
public:
MinecraftInstance(const QString& rootDir, SettingsObject* settings, QObject* parent = 0);
MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
virtual ~MinecraftInstance() {};
/// Path to the instance's minecraft directory.

View File

@ -175,3 +175,5 @@ protected:
private:
QMap<QString, std::shared_ptr<Setting>> m_settings;
};
typedef std::shared_ptr<SettingsObject> SettingsObjectPtr;