From 4e9006769e3554524096d45f8a1ce16ccfa78bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 6 Feb 2013 07:07:44 +0100 Subject: [PATCH 01/15] Some minor changes in the instance model and control --- data/instancemodel.cpp | 5 +---- gui/mainwindow.ui | 12 +++++++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/data/instancemodel.cpp b/data/instancemodel.cpp index 239be5c50..44d2844bd 100644 --- a/data/instancemodel.cpp +++ b/data/instancemodel.cpp @@ -143,12 +143,9 @@ QVariant InstanceModel::data ( const QModelIndex& index, int role ) const if (!index.isValid()) return QVariant(); - if (role != Qt::DisplayRole) - return QVariant(); - InstanceModelItem *item = static_cast(index.internalPointer()); - return item->data(index.column()); + return item->data(role); } QModelIndex InstanceModel::index ( int row, int column, const QModelIndex& parent ) const diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui index ccc7e777f..5abfb37db 100644 --- a/gui/mainwindow.ui +++ b/gui/mainwindow.ui @@ -34,7 +34,17 @@ 0 - + + + true + + + true + + + false + + From 4b1680f2428f33dc8ecbf3f4f4b964b0a02e7e06 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 14 Feb 2013 22:40:00 -0600 Subject: [PATCH 02/15] Started reworking the instance system. --- CMakeLists.txt | 20 +- data/appsettings.h | 7 +- data/{stdinstance.cpp => inst/instance.cpp} | 7 +- data/inst/instance.h | 320 ++++++++++++++++++ data/{stdinstance.h => inst/instancelist.cpp} | 15 +- data/inst/instancelist.h | 39 +++ data/instancebase.cpp | 109 ------ data/instancebase.h | 58 ---- data/instancemodel.h | 6 +- data/{siglist_imp.h => siglist_impl.h} | 0 data/version/instversion.cpp | 32 ++ data/version/instversion.h | 51 +++ data/version/instversionlist.cpp | 21 ++ data/version/instversionlist.h | 43 +++ 14 files changed, 533 insertions(+), 195 deletions(-) rename data/{stdinstance.cpp => inst/instance.cpp} (83%) create mode 100644 data/inst/instance.h rename data/{stdinstance.h => inst/instancelist.cpp} (72%) create mode 100644 data/inst/instancelist.h delete mode 100644 data/instancebase.cpp delete mode 100644 data/instancebase.h rename data/{siglist_imp.h => siglist_impl.h} (100%) create mode 100644 data/version/instversion.cpp create mode 100644 data/version/instversion.h create mode 100644 data/version/instversionlist.cpp create mode 100644 data/version/instversionlist.h diff --git a/CMakeLists.txt b/CMakeLists.txt index dbe86a833..1fcff14aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,13 +93,17 @@ main.cpp data/appsettings.cpp data/inifile.cpp -data/instancebase.cpp -data/instancemodel.cpp -data/stdinstance.cpp +#data/instancemodel.cpp data/version.cpp data/userinfo.cpp data/loginresponse.cpp +data/inst/instance.cpp +data/inst/instancelist.cpp + +data/version/instversion.cpp +data/version/instversionlist.cpp + gui/mainwindow.cpp gui/modeditwindow.cpp gui/settingsdialog.cpp @@ -127,14 +131,18 @@ gui/taskdialog.h data/appsettings.h data/inifile.h -data/instancebase.h data/instancemodel.h -data/stdinstance.h data/version.h data/userinfo.h data/loginresponse.h data/siglist.h -data/siglist_imp.h +data/siglist_impl.h + +data/inst/instance.h +data/inst/instancelist.h + +data/version/instversion.h +data/version/instversionlist.h util/apputils.h util/pathutils.h diff --git a/data/appsettings.h b/data/appsettings.h index a9068bfdf..8a786db02 100644 --- a/data/appsettings.h +++ b/data/appsettings.h @@ -39,8 +39,6 @@ #define DEFINE_SETTING(name, valType, defVal) \ DEFINE_SETTING_ADVANCED(name, STR_VAL(name), valType, defVal) -#define DEFINE_OVERRIDE_SETTING(overrideName) \ - class SettingsBase : public QObject { @@ -91,7 +89,6 @@ public: DEFINE_SETTING(PreLaunchCommand, QString, "") DEFINE_SETTING(PostExitCommand, QString, "") -protected: virtual QVariant getValue(const QString& name, QVariant defVal = QVariant()) const = 0; virtual void setValue(const QString& name, QVariant val) = 0; }; @@ -104,10 +101,10 @@ public: QSettings& getConfig() { return config; } -protected: virtual QVariant getValue(const QString &name, QVariant defVal = QVariant()) const; virtual void setValue(const QString& name, QVariant val); - + +protected: QSettings config; }; diff --git a/data/stdinstance.cpp b/data/inst/instance.cpp similarity index 83% rename from data/stdinstance.cpp rename to data/inst/instance.cpp index 4618f5ca8..5cde22334 100644 --- a/data/stdinstance.cpp +++ b/data/inst/instance.cpp @@ -13,10 +13,9 @@ * limitations under the License. */ -#include "stdinstance.h" +#include "instance.h" -StdInstance::StdInstance(QString rootDir, QObject* parent) : - InstanceBase(rootDir, parent) +Instance::Instance(QObject *parent) : + SettingsBase(parent) { - } diff --git a/data/inst/instance.h b/data/inst/instance.h new file mode 100644 index 000000000..6b1991b64 --- /dev/null +++ b/data/inst/instance.h @@ -0,0 +1,320 @@ +/* Copyright 2013 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. + */ + +#ifndef INSTANCE_H +#define INSTANCE_H + +#include +#include + +#include "data/appsettings.h" +#include "data/inifile.h" + +#define DEFINE_OVERRIDDEN_SETTING_ADVANCED(funcName, cfgEntryName, typeName) \ + typeName get ## funcName() const { return getField(cfgEntryName, settings->get ## funcName()).value(); } + +#define DEFINE_OVERRIDDEN_SETTING(funcName, typeName) \ + DEFINE_OVERRIDDEN_SETTING_ADVANCED(funcName, STR_VAL(funcName), typeName) + +class InstanceList; + +/*! + * \brief Base class for instances. + * This class implements many functions that are common between instances and + * provides a standard interface for all instances. + * + * To create a new instance type, create a new class inheriting from this class + * and implement the pure virtual functions. + */ +class Instance : public SettingsBase +{ + Q_OBJECT +public: + explicit Instance(QObject *parent = 0); + + // Please, for the sake of my (and everyone else's) sanity, at least keep this shit + // *somewhat* organized. Also, documentation is semi-important here. Please don't + // leave undocumented stuff behind. + + + //////// STUFF //////// + + /*! + * \brief Get the instance's ID. + * This is a unique identifier string that is, by default, set to the + * instance's folder name. It's not always the instance's folder name, + * however, as any class deriving from Instance can override the id() + * method and change how the ID is determined. The instance's ID + * should always remain constant. Undefined behavior results if an + * already loaded instance's ID changes. + * + * \return The instance's ID. + */ + virtual QString id(); + + /*! + * \brief Gets the path to the instance's root directory. + * \return The path to the instance's root directory. + */ + virtual QString rootDir(); + + /*! + * \brief Gets the instance list that this instance is a part of. + * Returns NULL if this instance is not in a list + * (the parent is not an InstanceList). + * \return A pointer to the InstanceList containing this instance. + */ + virtual InstanceList *instList(); + + + /*! + * \brief Gets this instance's group. + * This function is used by the instance grouping system and should + * not be touched by classes deriving from Instance. + * \return The instance's group name. + * \sa setGroup() + */ + QString group() const { return m_group; } + + /*! + * \brief Sets the instance's group. + * \param group The instance's new group name. + * \sa group() + */ + void setGroup(const QString &group) { m_group = group; emit groupChanged(this, group); } + + + //////// FIELDS AND SETTINGS //////// + // Fields are options stored in the instance's config file that are specific + // to instances (not a part of SettingsBase). Settings are things overridden + // from SettingsBase. + + + ////// Fields ////// + + //// General Info //// + + /*! + * \brief Gets this instance's name. + * This is the name that will be displayed to the user. + * \return The instance's name. + * \sa setName + */ + virtual QString name() { return getField("name", "Unnamed Instance").value(); } + + /*! + * \brief Sets the instance's name + * \param val The instance's new name. + */ + virtual void setName(QString val) { setField("name", val); } + + /*! + * \brief Gets the instance's icon key. + * \return The instance's icon key. + * \sa setIconKey() + */ + virtual QString iconKey() const { return getField("iconKey", "default").value(); } + + /*! + * \brief Sets the instance's icon key. + * \param val The new icon key. + */ + virtual void setIconKey(QString val) { setField("iconKey", val); } + + + /*! + * \brief Gets the instance's notes. + * \return The instances notes. + */ + virtual QString notes() const { return getField("notes", "").value(); } + + /*! + * \brief Sets the instance's notes. + * \param val The instance's new notes. + */ + virtual void setNotes(QString val) { setField("notes", val); } + + + /*! + * \brief Checks if the instance's minecraft.jar needs to be rebuilt. + * If this is true, the instance's mods will be reinstalled to its + * minecraft.jar file. This value is automatically set to true when + * the jar mod list changes. + * \return Whether or not the instance's jar file should be rebuilt. + */ + virtual bool shouldRebuild() const { return getField("NeedsRebuild", false).value(); } + + /*! + * \brief Sets whether or not the instance's minecraft.jar needs to be rebuilt. + * \param val Whether the instance's minecraft needs to be rebuilt or not. + */ + virtual void setShouldRebuild(bool val) { setField("NeedsRebuild", val); } + + + //// Version Stuff //// + + /*! + * \brief Sets the instance's current version. + * This value represents the instance's current version. If this value + * is different from intendedVersion(), the instance should be updated. + * This value is updated by the updateCurrentVersion() function. + * \return A string representing the instance's current version. + */ + virtual QString currentVersion() { return getField("JarVersion", "Unknown").value(); } + + /*! + * \brief Sets the instance's current version. + * This is used to keep track of the instance's current version. Don't + * mess with this unless you know what you're doing. + * \param val The new value. + */ + virtual void setCurrentVersion(QString val) { setField("JarVersion", val); } + + + /*! + * \brief Gets the version of LWJGL that this instance should use. + * If no LWJGL version is specified in the instance's config file, + * defaults to "Mojang" + * \return The instance's LWJGL version. + */ + virtual QString lwjglVersion() { return getField("LwjglVersion", "Mojang").value(); } + + /*! + * \brief Sets the version of LWJGL that this instance should use. + * \param val The LWJGL version to use + */ + virtual void setLWJGLVersion(QString val) { setField("LwjglVersion", val); } + + + /*! + * \brief Gets the version that this instance should try to update to. + * If this value differs from currentVersion(), the instance will + * download the intended version when it launches. + * \return The instance's intended version. + */ + virtual QString intendedVersion() { return getField("IntendedJarVersion", currentVersion()).value(); } + + /*! + * \brief Sets the version that this instance should try to update to. + * \param val The instance's new intended version. + */ + virtual void setIntendedVersion(QString val) { setField("IntendedJarVersion", val); } + + + + //// Timestamps //// + + /*! + * \brief Gets the time that the instance was last launched. + * Measured in milliseconds since epoch. QDateTime::currentMSecsSinceEpoch() + * \return The time that the instance was last launched. + */ + virtual qint64 lastLaunch() { return getField("lastLaunchTime", 0).value(); } + + /*! + * \brief Sets the time that the instance was last launched. + * \param val The time to set. Defaults to QDateTime::currentMSecsSinceEpoch() + */ + virtual void setLastLaunch(qint64 val = QDateTime::currentMSecsSinceEpoch()) + { setField("lastLaunchTime", val); } + + + ////// Settings ////// + + //// Java Settings //// + DEFINE_OVERRIDDEN_SETTING_ADVANCED(JavaPath, JPATHKEY, QString) + DEFINE_OVERRIDDEN_SETTING(JvmArgs, QString) + + //// Custom Commands //// + DEFINE_OVERRIDDEN_SETTING(PreLaunchCommand, QString) + DEFINE_OVERRIDDEN_SETTING(PostExitCommand, QString) + + //// Memory //// + DEFINE_OVERRIDDEN_SETTING(MinMemAlloc, int) + DEFINE_OVERRIDDEN_SETTING(MaxMemAlloc, int) + + //// Auto login //// + DEFINE_OVERRIDDEN_SETTING(AutoLogin, bool) + + // This little guy here is to keep Qt Creator from being a dumbass and + // auto-indenting the lines below the macros. Seriously, it's really annoying. + ; + + + //////// OTHER FUNCTIONS //////// + + //// Version System //// + + /*! + * \brief Checks whether or not the currentVersion of the instance needs to be updated. + * If this returns true, updateCurrentVersion is called. In the + * standard instance, this is determined by checking a timestamp + * stored in the instance config file against the last modified time of Minecraft.jar. + * \return True if updateCurrentVersion() should be called. + */ + virtual bool shouldUpdateCurrentVersion() = 0; + + /*! + * \brief Updates the current version. + * This function should first set the current version timestamp + * (setCurrentVersionTimestamp()) to the current time. Next, if + * keepCurrent is false, this function should check what the + * instance's current version is and call setCurrentVersion() to + * update it. This function will automatically be called when the + * instance is loaded if shouldUpdateCurrentVersion returns true. + * \param keepCurrent If true, only the version timestamp will be updated. + */ + virtual void updateCurrentVersion(bool keepCurrent = false) = 0; + +signals: + /*! + * \brief Signal emitted when the instance's group changes. + * \param inst Pointer to the instance whose group changed. + * \param newGroup The instance's new group. + */ + void groupChanged(Instance *inst, QString newGroup); + +protected: + /*! + * \brief Gets the value of the given field in the instance's config file. + * If the value isn't in the config file, defVal is returned instead. + * \param name The name of the field in the config file. + * \param defVal The default value. + * \return The value of the given field or defVal if the field doesn't exist. + * \sa setField() + */ + virtual QVariant getField(const QString &name, QVariant defVal = QVariant()) const; + + /*! + * \brief Sets the value of the given field in the config file. + * \param name The name of the field in the config file. + * \param val The value to set the field to. + * \sa getField() + */ + virtual void setField(const QString &name, QVariant val); + + // Overrides for SettingBase stuff. + virtual QVariant getValue(const QString &name, QVariant defVal = QVariant()) const + { return settings->getValue(name, defVal); } + virtual void setValue(const QString &name, QVariant val) + { setField(name, val); } + + INIFile config; + +private: + QString m_group; +}; + +#endif // INSTANCE_H diff --git a/data/stdinstance.h b/data/inst/instancelist.cpp similarity index 72% rename from data/stdinstance.h rename to data/inst/instancelist.cpp index 79b87601f..62367ed6b 100644 --- a/data/stdinstance.h +++ b/data/inst/instancelist.cpp @@ -13,16 +13,11 @@ * limitations under the License. */ -#ifndef STDINSTANCE_H -#define STDINSTANCE_H +#include "instancelist.h" -#include "instancebase.h" +#include "data/siglist_impl.h" -// Standard client instance. -class StdInstance : public InstanceBase +InstanceList::InstanceList(QObject *parent) : + QObject(parent) { -public: - explicit StdInstance(QString rootDir, QObject *parent = 0); -}; - -#endif // STDINSTANCE_H +} diff --git a/data/inst/instancelist.h b/data/inst/instancelist.h new file mode 100644 index 000000000..72dec5f0c --- /dev/null +++ b/data/inst/instancelist.h @@ -0,0 +1,39 @@ +/* Copyright 2013 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. + */ + +#ifndef INSTANCELIST_H +#define INSTANCELIST_H + +#include + +#include + +#include "data/siglist.h" + +class Instance; + +class InstanceList : public QObject, SigList> +{ + Q_OBJECT +public: + explicit InstanceList(QObject *parent = 0); + +signals: + +public slots: + +}; + +#endif // INSTANCELIST_H diff --git a/data/instancebase.cpp b/data/instancebase.cpp deleted file mode 100644 index a5ef35a24..000000000 --- a/data/instancebase.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright 2013 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 "instancebase.h" - -#include -#include - -#include "../util/pathutils.h" - -InstanceBase::InstanceBase(QString dir, QObject *parent) : - QObject(parent), - rootDir(dir) -{ - QFileInfo cfgFile(PathCombine(rootDir, "instance.cfg")); - - if (cfgFile.exists()) - { - if(!config.loadFile(cfgFile.absoluteFilePath())) - { - QString debugmsg("Can't load instance config file for instance "); - debugmsg+= getInstID(); - qDebug(debugmsg.toLocal8Bit()); - } - } - else - { - QString debugmsg("Can't find instance config file for instance "); - debugmsg+= getInstID(); - debugmsg += " : "; - debugmsg += - debugmsg+=" ... is this an instance even?"; - qDebug(debugmsg.toLocal8Bit()); - } - currentGroup = nullptr; -} - -QString InstanceBase::getRootDir() const -{ - return rootDir; -} - - -///////////// Config Values ///////////// - -// Name -QString InstanceBase::getInstName() const -{ - return config.get("name", "Unnamed").toString(); -} - -void InstanceBase::setInstName(QString name) -{ - config.set("name", name); -} - -QString InstanceBase::getInstID() const -{ - return QDir(rootDir).dirName(); -} - -InstanceModelItem* InstanceBase::getParent() const -{ - return currentGroup; -} - -QVariant InstanceBase::data ( int role ) const -{ - switch(role) - { - case Qt::DisplayRole: - return getInstName(); - default: - return QVariant(); - } -} -int InstanceBase::getRow() const -{ - return currentGroup->getIndexOf((InstanceBase*)this); -} - -InstanceModelItem* InstanceBase::getChild ( int index ) const -{ - return nullptr; -} -InstanceModel* InstanceBase::getModel() const -{ - return currentGroup->getModel(); -} -IMI_type InstanceBase::getModelItemType() const -{ - return IMI_Instance; -} -int InstanceBase::numChildren() const -{ - return 0; -} diff --git a/data/instancebase.h b/data/instancebase.h deleted file mode 100644 index fa043c5fb..000000000 --- a/data/instancebase.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2013 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. - */ - -#ifndef INSTANCEBASE_H -#define INSTANCEBASE_H - -#include -#include - -#include "../data/inifile.h" -#include "instancemodel.h" - -class InstanceBase : public QObject, public InstanceModelItem -{ - friend class InstanceGroup; - Q_OBJECT -public: - explicit InstanceBase(QString rootDir, QObject *parent = 0); - - QString getRootDir() const; - - QString getInstName() const; - void setInstName(QString name); - - QString getInstID() const; - - virtual IMI_type getModelItemType() const; - virtual InstanceModelItem* getParent() const; - virtual int numChildren() const; - virtual InstanceModelItem* getChild ( int index ) const; - virtual InstanceModel* getModel() const; - virtual QVariant data ( int column ) const; - virtual int getRow() const; - -private: - void setGroup ( InstanceGroup* group ) - { - currentGroup = group; - }; - - QString rootDir; - INIFile config; - InstanceGroup * currentGroup; -}; - -#endif // INSTANCEBASE_H diff --git a/data/instancemodel.h b/data/instancemodel.h index 4bd348310..9678fef01 100644 --- a/data/instancemodel.h +++ b/data/instancemodel.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef INSTANCELIST_H -#define INSTANCELIST_H +#ifndef INSTANCEMODEL_H +#define INSTANCEMODEL_H #include #include @@ -134,4 +134,4 @@ private: InstanceGroup * implicitGroup; }; -#endif // INSTANCELIST_H +#endif // INSTANCEMODEL_H diff --git a/data/siglist_imp.h b/data/siglist_impl.h similarity index 100% rename from data/siglist_imp.h rename to data/siglist_impl.h diff --git a/data/version/instversion.cpp b/data/version/instversion.cpp new file mode 100644 index 000000000..1493153af --- /dev/null +++ b/data/version/instversion.cpp @@ -0,0 +1,32 @@ +/* Copyright 2013 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 "instversion.h" +#include "instversionlist.h" + +InstVersion::InstVersion(InstVersionList *parent) : + QObject(parent) +{ + +} + +InstVersionList *InstVersion::versionList() const +{ + // Parent should *always* be an InstVersionList + if (!parent() || !parent()->inherits("InstVersionList")) + return NULL; + else + return (InstVersionList *)parent(); +} diff --git a/data/version/instversion.h b/data/version/instversion.h new file mode 100644 index 000000000..361563fd7 --- /dev/null +++ b/data/version/instversion.h @@ -0,0 +1,51 @@ +/* Copyright 2013 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. + */ + +#ifndef INSTVERSION_H +#define INSTVERSION_H + +#include + +class InstVersionList; + +class InstVersion : public QObject +{ + Q_OBJECT +public: + // Constructs a new InstVersion with the given parent. The parent *must* + // be the InstVersionList that contains this InstVersion. The InstVersion + // should be added to the list immediately after being created as any calls + // to id() will likely fail unless the InstVersion is in a list. + explicit InstVersion(InstVersionList *parent = 0); + + // Returns this InstVersion's ID. This is usually just the InstVersion's index + // within its InstVersionList, but not always. + // If this InstVersion is not in an InstVersionList, returns -1. + virtual int id() const = 0; + + // Returns this InstVersion's name. This is displayed to the user in the GUI + // and is usually just the version number ("1.4.7"), for example. + virtual QString name() const = 0; + + // Returns this InstVersion's name. This is usually displayed to the user + // in the GUI and specifies what kind of version this is. For example: it + // could be "Snapshot", "Latest Version", "MCNostalgia", etc. + virtual QString type() const = 0; + + // Returns the version list that this InstVersion is a part of. + virtual InstVersionList *versionList() const; +}; + +#endif // INSTVERSION_H diff --git a/data/version/instversionlist.cpp b/data/version/instversionlist.cpp new file mode 100644 index 000000000..ab57f94c9 --- /dev/null +++ b/data/version/instversionlist.cpp @@ -0,0 +1,21 @@ +/* Copyright 2013 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 "instversionlist.h" + +InstVersionList::InstVersionList() : + QObject(NULL) +{ +} diff --git a/data/version/instversionlist.h b/data/version/instversionlist.h new file mode 100644 index 000000000..f79bc1b03 --- /dev/null +++ b/data/version/instversionlist.h @@ -0,0 +1,43 @@ +/* Copyright 2013 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. + */ + +#ifndef INSTVERSIONLIST_H +#define INSTVERSIONLIST_H + +#include + +class InstVersion; + +// Class that each instance type's version list derives from. Version lists are +// the lists that keep track of the available game versions for that instance. +// This list will not be loaded on startup. It will be loaded when the list's +// load function is called. +class InstVersionList : public QObject +{ + Q_OBJECT +public: + explicit InstVersionList(); + + // Reloads the version list. + virtual void loadVersionList() = 0; + + // Gets the version at the given index. + virtual const InstVersion *at(int i) const = 0; + + // Returns the number of versions in the list. + virtual int count() const = 0; +}; + +#endif // INSTVERSIONLIST_H From 15c7efffa1af8c7b4fba710c30c53b6126bfa9db Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 18 Feb 2013 14:50:11 -0600 Subject: [PATCH 03/15] Added InstanceLoader and InstanceType headers. --- CMakeLists.txt | 4 ++ data/inst/instance.cpp | 2 +- data/inst/instance.h | 4 +- data/inst/instanceloader.cpp | 21 ++++++++ data/inst/instanceloader.h | 94 ++++++++++++++++++++++++++++++++++++ data/inst/instancetype.cpp | 21 ++++++++ data/inst/instancetype.h | 81 +++++++++++++++++++++++++++++++ 7 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 data/inst/instanceloader.cpp create mode 100644 data/inst/instanceloader.h create mode 100644 data/inst/instancetype.cpp create mode 100644 data/inst/instancetype.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 50961ef74..3916d0897 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,8 @@ data/version.cpp data/userinfo.cpp data/loginresponse.cpp +data/inst/instanceloader.cpp +data/inst/instancetype.cpp data/inst/instance.cpp data/inst/instancelist.cpp @@ -144,6 +146,8 @@ data/loginresponse.h data/siglist.h data/siglist_impl.h +data/inst/instanceloader.h +data/inst/instancetype.h data/inst/instance.h data/inst/instancelist.h diff --git a/data/inst/instance.cpp b/data/inst/instance.cpp index 5cde22334..d2240bc56 100644 --- a/data/inst/instance.cpp +++ b/data/inst/instance.cpp @@ -15,7 +15,7 @@ #include "instance.h" -Instance::Instance(QObject *parent) : +Instance::Instance(const QString &rootDir, QObject *parent) : SettingsBase(parent) { } diff --git a/data/inst/instance.h b/data/inst/instance.h index 6b1991b64..1b282b036 100644 --- a/data/inst/instance.h +++ b/data/inst/instance.h @@ -42,7 +42,7 @@ class Instance : public SettingsBase { Q_OBJECT public: - explicit Instance(QObject *parent = 0); + explicit Instance(const QString &rootDir, QObject *parent = 0); // Please, for the sake of my (and everyone else's) sanity, at least keep this shit // *somewhat* organized. Also, documentation is semi-important here. Please don't @@ -315,6 +315,8 @@ protected: private: QString m_group; + + QString m_rootDir; }; #endif // INSTANCE_H diff --git a/data/inst/instanceloader.cpp b/data/inst/instanceloader.cpp new file mode 100644 index 000000000..59fed9518 --- /dev/null +++ b/data/inst/instanceloader.cpp @@ -0,0 +1,21 @@ +/* Copyright 2013 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 "instanceloader.h" + +InstanceLoader::InstanceLoader(QObject *parent) : + QObject(parent) +{ +} diff --git a/data/inst/instanceloader.h b/data/inst/instanceloader.h new file mode 100644 index 000000000..943a9b2c3 --- /dev/null +++ b/data/inst/instanceloader.h @@ -0,0 +1,94 @@ +/* Copyright 2013 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. + */ + +#ifndef INSTANCELOADER_H +#define INSTANCELOADER_H + +#include + +class InstanceType; +class Instance; + +/*! + * \brief The InstanceLoader is a singleton that manages all of the instance types and handles loading and creating instances. + * Instance types are registered with the instance loader through its registerInstType() function. + * Creating instances is done through the InstanceLoader's createInstance() function. This function takes + */ +class InstanceLoader : public QObject +{ + Q_OBJECT +public: + static InstanceLoader instLoader; + + /*! + * \brief Error codes returned by functions in the InstanceLoader and InstanceType classes. + * NoError indicates that no error occurred. + * OtherError indicates that an unspecified error occurred. + * TypeIDExists is returned by registerInstanceType() if the ID of the type being registered already exists. + * + * TypeNotRegistered is returned by createInstance() and loadInstance() when the given type is not registered. + * InstExists is returned by createInstance() if the given instance directory is already an instance. + * NotAnInstance is returned by loadInstance() if the given instance directory is not a valid instance. + */ + enum InstTypeError + { + NoError = 0, + OtherError, + + TypeIDExists, + + TypeNotRegistered, + InstExists, + NotAnInstance + }; + + /*! + * \brief Registers the given InstanceType with the instance loader. + * This causes the instance loader to take ownership of the given + * instance type (meaning the instance type's parent will be set to + * the instance loader). + * \param type The InstanceType to register. + * \return An InstTypeError error code. + * TypeIDExists if the given type's is already registered to another instance type. + */ + InstTypeError registerInstanceType(InstanceType *type); + + /*! + * \brief Creates an instance with the given type and stores it in inst. + * \param inst Pointer to store the created instance in. + * \param type The type of instance to create. + * \param instDir The instance's directory. + * \return An InstTypeError error code. + * TypeNotRegistered if the given type is not registered with the InstanceLoader. + * InstExists if the given instance directory is already an instance. + */ + InstTypeError createInstance(Instance *inst, const InstanceType *type, const QString &instDir); + + /*! + * \brief Loads an instance from the given directory. + * \param inst Pointer to store the loaded instance in. + * \param type The type of instance to load. + * \param instDir The instance's directory. + * \return An InstTypeError error code. + * TypeNotRegistered if the given type is not registered with the InstanceLoader. + * NotAnInstance if the given instance directory isn't a valid instance. + */ + InstTypeError loadInstance(Instance *inst, const InstanceType *type, const QString &instDir); + +private: + explicit InstanceLoader(QObject *parent = 0); +}; + +#endif // INSTANCELOADER_H diff --git a/data/inst/instancetype.cpp b/data/inst/instancetype.cpp new file mode 100644 index 000000000..4f27542dd --- /dev/null +++ b/data/inst/instancetype.cpp @@ -0,0 +1,21 @@ +/* Copyright 2013 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 "instancetype.h" + +InstanceType::InstanceType(QObject *parent) : + QObject(parent) +{ +} diff --git a/data/inst/instancetype.h b/data/inst/instancetype.h new file mode 100644 index 000000000..1f1873107 --- /dev/null +++ b/data/inst/instancetype.h @@ -0,0 +1,81 @@ +/* Copyright 2013 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. + */ + +#ifndef INSTANCETYPE_H +#define INSTANCETYPE_H + +#include + +#include "instanceloader.h" + +/*! + * \brief The InstanceType class is a base class for all instance types. + * It handles loading and creating instances of a certain type. There should be + * one of these for each type of instance and they should be registered with the + * InstanceLoader. + * To create an instance, the InstanceLoader calls the type's createInstance() + * function. Loading is done through the loadInstance() function. + */ +class InstanceType : public QObject +{ + Q_OBJECT +public: + explicit InstanceType(QObject *parent = 0); + + /*! + * \brief Gets the ID for this instance type. + * By default this is the name of the Instance class that this type + * creates, but this can be changed by overriding this function. + * The type ID should be unique as it is used to identify the type + * of instances when they are loaded. + * Changing this value at runtime results in undefined behavior. + * \return This instance type's ID string. + */ + virtual QString typeID() const = 0; + + /*! + * \brief Gets the name of this instance type as it is displayed to the user. + * \return The instance type's display name. + */ + virtual QString displayName() const = 0; + + /*! + * \brief Gets a longer, more detailed description of this instance type. + * \return The instance type's description. + */ + virtual QString description() const = 0; + + /*! + * \brief Creates an instance and stores it in inst. + * \param inst Pointer to store the created instance in. + * \param instDir The instance's directory. + * \return An InstTypeError error code. + * TypeNotRegistered if the given type is not registered with the InstanceLoader. + * InstExists if the given instance directory is already an instance. + */ + virtual InstanceLoader::InstTypeError createInstance(Instance *inst, const QString &instDir) = 0; + + /*! + * \brief Loads an instance from the given directory. + * \param inst Pointer to store the loaded instance in. + * \param instDir The instance's directory. + * \return An InstTypeError error code. + * TypeNotRegistered if the given type is not registered with the InstanceLoader. + * NotAnInstance if the given instance directory isn't a valid instance. + */ + virtual InstanceLoader::InstTypeError loadInstance(Instance *inst, const QString &instDir) = 0; +}; + +#endif // INSTANCETYPE_H From d3c4db8f3444c8531cb5a02ce3c95d5673ffb1a5 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 18 Feb 2013 15:39:01 -0600 Subject: [PATCH 04/15] Implemented instance loader. --- data/inst/instanceloader.cpp | 60 ++++++++++++++++++++++++++++++++++++ data/inst/instanceloader.h | 25 ++++++++++++++- data/inst/instancetype.h | 8 +++-- 3 files changed, 90 insertions(+), 3 deletions(-) diff --git a/data/inst/instanceloader.cpp b/data/inst/instanceloader.cpp index 59fed9518..bc43c0611 100644 --- a/data/inst/instanceloader.cpp +++ b/data/inst/instanceloader.cpp @@ -15,7 +15,67 @@ #include "instanceloader.h" +#include "instancetype.h" + InstanceLoader::InstanceLoader(QObject *parent) : QObject(parent) { } + + +InstanceLoader::InstTypeError InstanceLoader::registerInstanceType(InstanceType *type) +{ + // Check to see if the type ID exists. + if (m_typeMap.contains(type->typeID())) + return TypeIDExists; + + // Set the parent to this. + type->setParent(this); + + // Add it to the map. + m_typeMap.insert(type->typeID(), type); + return NoError; +} + +InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *inst, + const InstanceType *type, + const QString &instDir) +{ + // Check if the type is registered. + if (!type || findType(type->typeID()) != type) + return TypeNotRegistered; + + // Create the instance. + return type->createInstance(inst, instDir); +} + +InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, + const InstanceType *type, + const QString &instDir) +{ + // Check if the type is registered. + if (!type || findType(type->typeID()) != type) + return TypeNotRegistered; + + return type->loadInstance(inst, instDir); +} + +const InstanceType *InstanceLoader::findType(const QString &id) +{ + if (!m_typeMap.contains(id)) + return NULL; + else + return m_typeMap[id]; +} + +InstTypeList InstanceLoader::typeList() +{ + InstTypeList typeList; + + for (auto iter = m_typeMap.begin(); iter != m_typeMap.end(); iter++) + { + typeList.append(*iter); + } + + return typeList; +} diff --git a/data/inst/instanceloader.h b/data/inst/instanceloader.h index 943a9b2c3..1a8a598ff 100644 --- a/data/inst/instanceloader.h +++ b/data/inst/instanceloader.h @@ -17,10 +17,14 @@ #define INSTANCELOADER_H #include +#include +#include class InstanceType; class Instance; +typedef QList InstTypeList; + /*! * \brief The InstanceLoader is a singleton that manages all of the instance types and handles loading and creating instances. * Instance types are registered with the instance loader through its registerInstType() function. @@ -41,6 +45,7 @@ public: * TypeNotRegistered is returned by createInstance() and loadInstance() when the given type is not registered. * InstExists is returned by createInstance() if the given instance directory is already an instance. * NotAnInstance is returned by loadInstance() if the given instance directory is not a valid instance. + * WrongInstType is returned by loadInstance() if the given instance directory's type doesn't match the given type. */ enum InstTypeError { @@ -51,7 +56,8 @@ public: TypeNotRegistered, InstExists, - NotAnInstance + NotAnInstance, + WrongInstType }; /*! @@ -84,11 +90,28 @@ public: * \return An InstTypeError error code. * TypeNotRegistered if the given type is not registered with the InstanceLoader. * NotAnInstance if the given instance directory isn't a valid instance. + * WrongInstType if the given instance directory's type isn't the same as the given type. */ InstTypeError loadInstance(Instance *inst, const InstanceType *type, const QString &instDir); + /*! + * \brief Finds an instance type with the given ID. + * If one cannot be found, returns NULL. + * \param id The ID of the type to find. + * \return The type with the given ID. NULL if none were found. + */ + const InstanceType *findType(const QString &id); + + /*! + * \brief Gets a list of the registered instance types. + * \return A list of instance types. + */ + InstTypeList typeList(); + private: explicit InstanceLoader(QObject *parent = 0); + + QMap m_typeMap; }; #endif // INSTANCELOADER_H diff --git a/data/inst/instancetype.h b/data/inst/instancetype.h index 1f1873107..ec3f5b87b 100644 --- a/data/inst/instancetype.h +++ b/data/inst/instancetype.h @@ -34,6 +34,8 @@ class InstanceType : public QObject public: explicit InstanceType(QObject *parent = 0); + friend class InstanceLoader; + /*! * \brief Gets the ID for this instance type. * By default this is the name of the Instance class that this type @@ -57,6 +59,7 @@ public: */ virtual QString description() const = 0; +protected: /*! * \brief Creates an instance and stores it in inst. * \param inst Pointer to store the created instance in. @@ -65,7 +68,7 @@ public: * TypeNotRegistered if the given type is not registered with the InstanceLoader. * InstExists if the given instance directory is already an instance. */ - virtual InstanceLoader::InstTypeError createInstance(Instance *inst, const QString &instDir) = 0; + virtual InstanceLoader::InstTypeError createInstance(Instance *inst, const QString &instDir) const = 0; /*! * \brief Loads an instance from the given directory. @@ -74,8 +77,9 @@ public: * \return An InstTypeError error code. * TypeNotRegistered if the given type is not registered with the InstanceLoader. * NotAnInstance if the given instance directory isn't a valid instance. + * WrongInstType if the given instance directory's type isn't an instance of this type. */ - virtual InstanceLoader::InstTypeError loadInstance(Instance *inst, const QString &instDir) = 0; + virtual InstanceLoader::InstTypeError loadInstance(Instance *inst, const QString &instDir) const = 0; }; #endif // INSTANCETYPE_H From 80cd8b33aa12933392bd2293a5e91ae696dbe6be Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 18 Feb 2013 16:58:53 -0600 Subject: [PATCH 05/15] Implemented Instance --- data/inst/instance.cpp | 34 ++++++++++++++++++++++++++++++++++ data/inst/instanceloader.cpp | 5 +++-- data/inst/instanceloader.h | 2 +- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/data/inst/instance.cpp b/data/inst/instance.cpp index d2240bc56..8561ed9f3 100644 --- a/data/inst/instance.cpp +++ b/data/inst/instance.cpp @@ -15,7 +15,41 @@ #include "instance.h" +#include + +#include "util/pathutils.h" + Instance::Instance(const QString &rootDir, QObject *parent) : SettingsBase(parent) { + m_rootDir = rootDir; + config.loadFile(PathCombine(rootDir, "instance.cfg")); +} + +QString Instance::id() +{ + return QFileInfo(rootDir()).baseName(); +} + +QString Instance::rootDir() +{ + return m_rootDir; +} + +InstanceList *Instance::instList() +{ + if (parent()->inherits("InstanceList")) + return (InstanceList *)parent(); + else + return NULL; +} + +QVariant Instance::getField(const QString &name, QVariant defVal) const +{ + return config.get(name, defVal); +} + +void Instance::setField(const QString &name, QVariant val) +{ + config.set(name, val); } diff --git a/data/inst/instanceloader.cpp b/data/inst/instanceloader.cpp index bc43c0611..1a53bfa7c 100644 --- a/data/inst/instanceloader.cpp +++ b/data/inst/instanceloader.cpp @@ -17,9 +17,10 @@ #include "instancetype.h" -InstanceLoader::InstanceLoader(QObject *parent) : - QObject(parent) +InstanceLoader::InstanceLoader() : + QObject(NULL) { + } diff --git a/data/inst/instanceloader.h b/data/inst/instanceloader.h index 1a8a598ff..b7092edc9 100644 --- a/data/inst/instanceloader.h +++ b/data/inst/instanceloader.h @@ -109,7 +109,7 @@ public: InstTypeList typeList(); private: - explicit InstanceLoader(QObject *parent = 0); + InstanceLoader(); QMap m_typeMap; }; From 6e5017e48b633e20bbba61ac2e7cd58e693aec4e Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 19 Feb 2013 12:15:22 -0600 Subject: [PATCH 06/15] Implemented loadList() stuff. --- CMakeLists.txt | 2 - data/inst/instance.h | 27 --- data/inst/instancelist.cpp | 59 ++++- data/inst/instancelist.h | 26 +- data/inst/instanceloader.cpp | 24 ++ data/inst/instanceloader.h | 54 +++-- data/instancemodel.cpp | 457 ----------------------------------- data/instancemodel.h | 137 ----------- gui/mainwindow.cpp | 9 +- gui/mainwindow.h | 4 +- 10 files changed, 145 insertions(+), 654 deletions(-) delete mode 100644 data/instancemodel.cpp delete mode 100644 data/instancemodel.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3916d0897..a01edccf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,6 @@ main.cpp data/appsettings.cpp data/inifile.cpp -#data/instancemodel.cpp data/version.cpp data/userinfo.cpp data/loginresponse.cpp @@ -139,7 +138,6 @@ gui/taskdialog.h data/appsettings.h data/inifile.h -data/instancemodel.h data/version.h data/userinfo.h data/loginresponse.h diff --git a/data/inst/instance.h b/data/inst/instance.h index 1b282b036..56e9d0b89 100644 --- a/data/inst/instance.h +++ b/data/inst/instance.h @@ -79,23 +79,6 @@ public: virtual InstanceList *instList(); - /*! - * \brief Gets this instance's group. - * This function is used by the instance grouping system and should - * not be touched by classes deriving from Instance. - * \return The instance's group name. - * \sa setGroup() - */ - QString group() const { return m_group; } - - /*! - * \brief Sets the instance's group. - * \param group The instance's new group name. - * \sa group() - */ - void setGroup(const QString &group) { m_group = group; emit groupChanged(this, group); } - - //////// FIELDS AND SETTINGS //////// // Fields are options stored in the instance's config file that are specific // to instances (not a part of SettingsBase). Settings are things overridden @@ -278,14 +261,6 @@ public: */ virtual void updateCurrentVersion(bool keepCurrent = false) = 0; -signals: - /*! - * \brief Signal emitted when the instance's group changes. - * \param inst Pointer to the instance whose group changed. - * \param newGroup The instance's new group. - */ - void groupChanged(Instance *inst, QString newGroup); - protected: /*! * \brief Gets the value of the given field in the instance's config file. @@ -314,8 +289,6 @@ protected: INIFile config; private: - QString m_group; - QString m_rootDir; }; diff --git a/data/inst/instancelist.cpp b/data/inst/instancelist.cpp index 62367ed6b..cbb89f051 100644 --- a/data/inst/instancelist.cpp +++ b/data/inst/instancelist.cpp @@ -17,7 +17,62 @@ #include "data/siglist_impl.h" -InstanceList::InstanceList(QObject *parent) : - QObject(parent) +#include +#include +#include + +#include "instance.h" +#include "instanceloader.h" + +#include "util/pathutils.h" + + +InstanceList::InstanceList(const QString &instDir, QObject *parent) : + QObject(parent), m_instDir(instDir) { + +} + +InstanceList::InstListError InstanceList::loadList() +{ + QDir dir(m_instDir); + QDirIterator iter(dir); + + while (iter.hasNext()) + { + QString subDir = iter.next(); + if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) + { + QSharedPointer inst; + InstanceLoader::InstTypeError error = InstanceLoader::loader. + loadInstance(inst.data(), subDir); + + if (inst.data() && error == InstanceLoader::NoError) + { + qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8()); + inst->setParent(this); + append(QSharedPointer(inst)); + } + else if (error != InstanceLoader::NotAnInstance) + { + QString errorMsg = QString("Failed to load instance %1: "). + arg(QFileInfo(subDir).baseName()).toUtf8(); + + switch (error) + { + case InstanceLoader::TypeNotRegistered: + errorMsg += "Instance type not found."; + break; + } + qDebug(errorMsg.toUtf8()); + } + else if (!inst.data()) + { + qDebug(QString("Error loading instance %1. Instance loader returned null."). + arg(QFileInfo(subDir).baseName()).toUtf8()); + } + } + } + + return NoError; } diff --git a/data/inst/instancelist.h b/data/inst/instancelist.h index 72dec5f0c..c43c4cc08 100644 --- a/data/inst/instancelist.h +++ b/data/inst/instancelist.h @@ -24,16 +24,34 @@ class Instance; -class InstanceList : public QObject, SigList> +class InstanceList : public QObject, public SigList> { Q_OBJECT public: - explicit InstanceList(QObject *parent = 0); + explicit InstanceList(const QString &instDir, QObject *parent = 0); -signals: + /*! + * \brief Error codes returned by functions in the InstanceList class. + * NoError Indicates that no error occurred. + * UnknownError indicates that an unspecified error occurred. + */ + enum InstListError + { + NoError = 0, + UnknownError + }; -public slots: + QString instDir() const { return m_instDir; } + /*! + * \brief Loads the instance list. + */ + InstListError loadList(); + + DEFINE_SIGLIST_SIGNALS(QSharedPointer); + SETUP_SIGLIST_SIGNALS(QSharedPointer); +protected: + QString m_instDir; }; #endif // INSTANCELIST_H diff --git a/data/inst/instanceloader.cpp b/data/inst/instanceloader.cpp index 1a53bfa7c..e80a0e9e7 100644 --- a/data/inst/instanceloader.cpp +++ b/data/inst/instanceloader.cpp @@ -15,8 +15,16 @@ #include "instanceloader.h" +#include + #include "instancetype.h" +#include "data/inifile.h" + +#include "util/pathutils.h" + +InstanceLoader InstanceLoader::loader; + InstanceLoader::InstanceLoader() : QObject(NULL) { @@ -61,6 +69,22 @@ InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, return type->loadInstance(inst, instDir); } +InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, + const QString &instDir) +{ + QFileInfo instConfig(PathCombine(instDir, "instance.cfg")); + + if (!instConfig.exists()) + return NotAnInstance; + + INIFile ini; + ini.loadFile(instConfig.path()); + QString typeName = ini.get("type", "StdInstance").toString(); + const InstanceType *type = findType(typeName); + + return loadInstance(inst, type, instDir); +} + const InstanceType *InstanceLoader::findType(const QString &id) { if (!m_typeMap.contains(id)) diff --git a/data/inst/instanceloader.h b/data/inst/instanceloader.h index b7092edc9..60c4e998b 100644 --- a/data/inst/instanceloader.h +++ b/data/inst/instanceloader.h @@ -34,18 +34,18 @@ class InstanceLoader : public QObject { Q_OBJECT public: - static InstanceLoader instLoader; + static InstanceLoader loader; /*! * \brief Error codes returned by functions in the InstanceLoader and InstanceType classes. - * NoError indicates that no error occurred. - * OtherError indicates that an unspecified error occurred. - * TypeIDExists is returned by registerInstanceType() if the ID of the type being registered already exists. - * - * TypeNotRegistered is returned by createInstance() and loadInstance() when the given type is not registered. - * InstExists is returned by createInstance() if the given instance directory is already an instance. - * NotAnInstance is returned by loadInstance() if the given instance directory is not a valid instance. - * WrongInstType is returned by loadInstance() if the given instance directory's type doesn't match the given type. + * + * - NoError indicates that no error occurred. + * - OtherError indicates that an unspecified error occurred. + * - TypeIDExists is returned by registerInstanceType() if the ID of the type being registered already exists. + * - TypeNotRegistered is returned by createInstance() and loadInstance() when the given type is not registered. + * - InstExists is returned by createInstance() if the given instance directory is already an instance. + * - NotAnInstance is returned by loadInstance() if the given instance directory is not a valid instance. + * - WrongInstType is returned by loadInstance() if the given instance directory's type doesn't match the given type. */ enum InstTypeError { @@ -62,41 +62,56 @@ public: /*! * \brief Registers the given InstanceType with the instance loader. - * This causes the instance loader to take ownership of the given - * instance type (meaning the instance type's parent will be set to - * the instance loader). + * This causes the instance loader to take ownership of the given + * instance type (meaning the instance type's parent will be set to + * the instance loader). + * * \param type The InstanceType to register. * \return An InstTypeError error code. - * TypeIDExists if the given type's is already registered to another instance type. + * - TypeIDExists if the given type's is already registered to another instance type. */ InstTypeError registerInstanceType(InstanceType *type); /*! * \brief Creates an instance with the given type and stores it in inst. + * * \param inst Pointer to store the created instance in. * \param type The type of instance to create. * \param instDir The instance's directory. * \return An InstTypeError error code. - * TypeNotRegistered if the given type is not registered with the InstanceLoader. - * InstExists if the given instance directory is already an instance. + * - TypeNotRegistered if the given type is not registered with the InstanceLoader. + * - InstExists if the given instance directory is already an instance. */ InstTypeError createInstance(Instance *inst, const InstanceType *type, const QString &instDir); /*! * \brief Loads an instance from the given directory. + * * \param inst Pointer to store the loaded instance in. * \param type The type of instance to load. * \param instDir The instance's directory. * \return An InstTypeError error code. - * TypeNotRegistered if the given type is not registered with the InstanceLoader. - * NotAnInstance if the given instance directory isn't a valid instance. - * WrongInstType if the given instance directory's type isn't the same as the given type. + * - TypeNotRegistered if the given type is not registered with the InstanceLoader. + * - NotAnInstance if the given instance directory isn't a valid instance. + * - WrongInstType if the given instance directory's type isn't the same as the given type. */ InstTypeError loadInstance(Instance *inst, const InstanceType *type, 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 InstTypeError error code. + * - TypeNotRegistered if the instance's type is not registered with the InstanceLoader. + * - NotAnInstance if the given instance directory isn't a valid instance. + */ + InstTypeError loadInstance(Instance *inst, const QString &instDir); + /*! * \brief Finds an instance type with the given ID. - * If one cannot be found, returns NULL. + * If one cannot be found, returns NULL. + * * \param id The ID of the type to find. * \return The type with the given ID. NULL if none were found. */ @@ -104,6 +119,7 @@ public: /*! * \brief Gets a list of the registered instance types. + * * \return A list of instance types. */ InstTypeList typeList(); diff --git a/data/instancemodel.cpp b/data/instancemodel.cpp deleted file mode 100644 index fbdb82126..000000000 --- a/data/instancemodel.cpp +++ /dev/null @@ -1,457 +0,0 @@ -/* Copyright 2013 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 "instancemodel.h" - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "data/stdinstance.h" -#include "util/pathutils.h" - -#define GROUP_FILE_FORMAT_VERSION 1 - -InstanceModel::InstanceModel( QObject* parent ) : - QAbstractItemModel() -{ -} - -InstanceModel::~InstanceModel() -{ - saveGroupInfo(); - for(int i = 0; i < groups.size(); i++) - { - delete groups[i]; - } -} - -void InstanceModel::addInstance( InstanceBase* inst, const QString& groupName ) -{ - auto group = getGroupByName(groupName); - group->addInstance(inst); -} - -void InstanceGroup::addInstance ( InstanceBase* inst ) -{ - instances.append(inst); - inst->setGroup(this); - // TODO: notify model. -} - - -void InstanceModel::initialLoad(QString dir) -{ - groupFileName = dir + "/instgroups.json"; - implicitGroup = new InstanceGroup("Ungrouped", this); - groups.append(implicitGroup); - - // temporary map from instance ID to group name - QMap groupMap; - - if (QFileInfo(groupFileName).exists()) - { - QFile groupFile(groupFileName); - - if (!groupFile.open(QIODevice::ReadOnly)) - { - // An error occurred. Ignore it. - qDebug("Failed to read instance group file."); - goto groupParseFail; - } - - QTextStream in(&groupFile); - QString jsonStr = in.readAll(); - groupFile.close(); - - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8(), &error); - - if (error.error != QJsonParseError::NoError) - { - qWarning(QString("Failed to parse instance group file: %1 at offset %2"). - arg(error.errorString(), QString::number(error.offset)).toUtf8()); - goto groupParseFail; - } - - if (!jsonDoc.isObject()) - { - qWarning("Invalid group file. Root entry should be an object."); - goto groupParseFail; - } - - QJsonObject rootObj = jsonDoc.object(); - - // Make sure the format version matches. - if (rootObj.value("formatVersion").toVariant().toInt() == GROUP_FILE_FORMAT_VERSION) - { - // Get the group list. - if (!rootObj.value("groups").isObject()) - { - qWarning("Invalid group list JSON: 'groups' should be an object."); - goto groupParseFail; - } - - // Iterate through the list. - QJsonObject groupList = rootObj.value("groups").toObject(); - - for (QJsonObject::iterator iter = groupList.begin(); - iter != groupList.end(); iter++) - { - QString groupName = iter.key(); - - // If not an object, complain and skip to the next one. - if (!iter.value().isObject()) - { - qWarning(QString("Group '%1' in the group list should " - "be an object.").arg(groupName).toUtf8()); - continue; - } - - QJsonObject groupObj = iter.value().toObject(); - - // Create the group object. - InstanceGroup *group = new InstanceGroup(groupName, this); - groups.push_back(group); - - // If 'hidden' isn't a bool value, just assume it's false. - if (groupObj.value("hidden").isBool() && groupObj.value("hidden").toBool()) - { - group->setHidden(groupObj.value("hidden").toBool()); - } - - if (!groupObj.value("instances").isArray()) - { - qWarning(QString("Group '%1' in the group list is invalid. " - "It should contain an array " - "called 'instances'.").arg(groupName).toUtf8()); - continue; - } - - // Iterate through the list of instances in the group. - QJsonArray instancesArray = groupObj.value("instances").toArray(); - - for (QJsonArray::iterator iter2 = instancesArray.begin(); - iter2 != instancesArray.end(); iter2++) - { - groupMap[(*iter2).toString()] = groupName; - } - } - } - } - -groupParseFail: - - qDebug("Loading instances"); - QDir instDir(dir); - QDirIterator iter(instDir); - - while (iter.hasNext()) - { - QString subDir = iter.next(); - if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) - { - // TODO Differentiate between different instance types. - InstanceBase* inst = new StdInstance(subDir); - QString instID = inst->getInstID(); - auto iter = groupMap.find(instID); - if(iter != groupMap.end()) - { - addInstance(inst,iter.value()); - } - else - { - addInstance(inst); - } - } - } -} - -int InstanceModel::columnCount ( const QModelIndex& parent ) const -{ - // for now... - return 1; -} - -QVariant InstanceModel::data ( const QModelIndex& index, int role ) const -{ - if (!index.isValid()) - return QVariant(); - - if (role != Qt::DisplayRole) - return QVariant(); - - InstanceModelItem *item = static_cast(index.internalPointer()); - - return item->data(index.column()); -} - -QModelIndex InstanceModel::index ( int row, int column, const QModelIndex& parent ) const -{ - if (!hasIndex(row, column, parent)) - return QModelIndex(); - - InstanceModelItem *parentItem; - - if (!parent.isValid()) - parentItem = (InstanceModelItem *) this; - else - parentItem = static_cast(parent.internalPointer()); - - InstanceModelItem *childItem = parentItem->getChild(row); - if (childItem) - return createIndex(row, column, childItem); - else - return QModelIndex(); - -} - -QModelIndex InstanceModel::parent ( const QModelIndex& index ) const -{ - if (!index.isValid()) - return QModelIndex(); - - InstanceModelItem *childItem = static_cast(index.internalPointer()); - InstanceModelItem *parentItem = childItem->getParent(); - - if (parentItem == this) - return QModelIndex(); - - return createIndex(parentItem->getRow(), 0, parentItem); -} - -int InstanceModel::rowCount ( const QModelIndex& parent ) const -{ - InstanceModelItem *parentItem; - if (parent.column() > 0) - return 0; - - if (!parent.isValid()) - parentItem = (InstanceModelItem*) this; - else - parentItem = static_cast(parent.internalPointer()); - - return parentItem->numChildren(); -} - -bool InstanceModel::saveGroupInfo() const -{ - /* - using namespace boost::property_tree; - ptree pt; - - pt.put("formatVersion", GROUP_FILE_FORMAT_VERSION); - - try - { - typedef QMap > GroupListMap; - - GroupListMap groupLists; - for (auto iter = instances.begin(); iter != instances.end(); iter++) - { - InstanceGroup *group = getInstanceGroup(*iter); - - if (group != nullptr) - groupLists[group].push_back(*iter); - } - - ptree groupsPtree; - for (auto iter = groupLists.begin(); iter != groupLists.end(); iter++) - { - auto group = iter.key(); - auto & gList = iter.value(); - - ptree groupTree; - - groupTree.put("hidden", group->isHidden()); - - ptree instList; - for (auto iter2 = gList.begin(); iter2 != gList.end(); iter2++) - { - std::string instID((*iter2)->getInstID().toUtf8()); - instList.push_back(std::make_pair("", ptree(instID))); - } - groupTree.put_child("instances", instList); - - groupsPtree.push_back(std::make_pair(std::string(group->getName().toUtf8()), groupTree)); - } - pt.put_child("groups", groupsPtree); - - write_json(groupFile.toStdString(), pt); - } - catch (json_parser_error e) - { -// wxLogError(_("Failed to read group list.\nJSON parser error at line %i: %s"), -// e.line(), wxStr(e.message()).c_str()); - return false; - } - catch (ptree_error e) - { -// wxLogError(_("Failed to save group list. Unknown ptree error.")); - return false; - } - - return true; - */ - return false; -} - -void InstanceModel::setInstanceGroup ( InstanceBase* inst, const QString& groupName ) -{ - /* - InstanceGroup *prevGroup = getInstanceGroup(inst); - - if (prevGroup != nullptr) - { - groupsMap.remove(inst); - } - - if (!groupName.isEmpty()) - { - InstanceGroup *newGroup = nullptr; - - for (auto iter = root->groups.begin(); iter != root->groups.end(); iter++) - { - if ((*iter)->getName() == groupName) - { - newGroup = *iter; - } - } - - if (newGroup == nullptr) - { - newGroup = new InstanceGroup(groupName, this); - root->groups.push_back(newGroup); - } - - groupsMap[inst] = newGroup; - } - - // TODO: propagate change, reflect in model, etc. - //InstanceGroupChanged(inst); - */ -} - -InstanceGroup* InstanceModel::getGroupByName ( const QString& name ) const -{ - for (auto iter = groups.begin(); iter != groups.end(); iter++) - { - if ((*iter)->getName() == name) - return *iter; - } - return nullptr; -} -/* -void InstanceModel::setGroupFile ( QString filename ) -{ - groupFile = filename; -}*/ - -int InstanceModel::numChildren() const -{ - return groups.count(); -} - -InstanceModelItem* InstanceModel::getChild ( int index ) const -{ - return groups[index]; -} - -QVariant InstanceModel::data ( int role ) const -{ - switch(role) - { - case Qt::DisplayRole: - return "name"; - } - return QVariant(); -} - - -InstanceGroup::InstanceGroup(const QString& name, InstanceModel *parent) -{ - this->name = name; - this->model = parent; - this->hidden = false; -} - -InstanceGroup::~InstanceGroup() -{ - for(int i = 0; i < instances.size(); i++) - { - delete instances[i]; - } -} - - -QString InstanceGroup::getName() const -{ - return name; -} - -void InstanceGroup::setName(const QString& name) -{ - this->name = name; - //TODO: propagate change -} - -InstanceModelItem* InstanceGroup::getParent() const -{ - return model; -} - -bool InstanceGroup::isHidden() const -{ - return hidden; -} - -void InstanceGroup::setHidden(bool hidden) -{ - this->hidden = hidden; - //TODO: propagate change -} - -int InstanceGroup::getRow() const -{ - return model->getIndexOf( this); -} - -InstanceModelItem* InstanceGroup::getChild ( int index ) const -{ - return instances[index]; -} - -int InstanceGroup::numChildren() const -{ - return instances.size(); -} - -QVariant InstanceGroup::data ( int role ) const -{ - switch(role) - { - case Qt::DisplayRole: - return name; - default: - return QVariant(); - } -} diff --git a/data/instancemodel.h b/data/instancemodel.h deleted file mode 100644 index 9678fef01..000000000 --- a/data/instancemodel.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Copyright 2013 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. - */ - -#ifndef INSTANCEMODEL_H -#define INSTANCEMODEL_H - -#include -#include -#include -#include - -enum IMI_type -{ - IMI_Root, - IMI_Group, - IMI_Instance -}; - -class InstanceModel; -class InstanceGroup; -class InstanceBase; - -class InstanceModelItem -{ - public: - virtual IMI_type getModelItemType() const = 0; - virtual InstanceModelItem * getParent() const = 0; - virtual int numChildren() const = 0; - virtual InstanceModelItem * getChild(int index) const = 0; - virtual InstanceModel * getModel() const = 0; - virtual QVariant data(int role) const = 0; - virtual int getRow() const = 0; -}; - -class InstanceGroup : public InstanceModelItem -{ -public: - InstanceGroup(const QString& name, InstanceModel * model); - ~InstanceGroup(); - - QString getName() const; - void setName(const QString& name); - - bool isHidden() const; - void setHidden(bool hidden); - - virtual IMI_type getModelItemType() const - { - return IMI_Group; - } - virtual InstanceModelItem* getParent() const; - virtual InstanceModelItem* getChild ( int index ) const; - virtual int numChildren() const; - virtual InstanceModel * getModel() const - { - return model; - }; - virtual QVariant data ( int column ) const; - int getIndexOf(InstanceBase * inst) - { - return instances.indexOf(inst); - }; - virtual int getRow() const; - void addInstance ( InstanceBase* inst ); -protected: - QString name; - InstanceModel * model; - QVector instances; - bool hidden; - int row; -}; - -class InstanceModel : public QAbstractItemModel, public InstanceModelItem -{ -public: - explicit InstanceModel(QObject *parent = 0); - ~InstanceModel(); - - virtual int columnCount ( const QModelIndex& parent = QModelIndex() ) const; - virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const; - virtual QModelIndex index ( int row, int column, const QModelIndex& parent = QModelIndex() ) const; - virtual QModelIndex parent ( const QModelIndex& child ) const; - virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const; - - void addInstance(InstanceBase *inst, const QString& groupName = "Ungrouped"); - void setInstanceGroup(InstanceBase *inst, const QString & groupName); - InstanceGroup* getGroupByName(const QString & name) const; - - void initialLoad(QString dir); - bool saveGroupInfo() const; - - virtual IMI_type getModelItemType() const - { - return IMI_Root; - } - virtual InstanceModelItem * getParent() const - { - return nullptr; - }; - virtual int numChildren() const; - virtual InstanceModelItem* getChild ( int index ) const; - virtual InstanceModel* getModel() const - { - return nullptr; - }; - virtual QVariant data ( int column ) const; - int getIndexOf(const InstanceGroup * grp) const - { - return groups.indexOf((InstanceGroup *) grp); - }; - virtual int getRow() const - { - return 0; - }; -signals: - -public slots: - -private: - QString groupFileName; - QVector groups; - InstanceGroup * implicitGroup; -}; - -#endif // INSTANCEMODEL_H diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index bc0840a07..d19d69dcf 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -29,6 +29,7 @@ #include "gui/logindialog.h" #include "gui/taskdialog.h" +#include "data/inst/instancelist.h" #include "data/appsettings.h" #include "data/version.h" @@ -36,7 +37,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), - ui(new Ui::MainWindow) + ui(new Ui::MainWindow), + instList(settings->getInstanceDir()) { ui->setupUi(this); @@ -45,8 +47,7 @@ MainWindow::MainWindow(QWidget *parent) : restoreGeometry(settings->getConfig().value("MainWindowGeometry", saveGeometry()).toByteArray()); restoreState(settings->getConfig().value("MainWindowState", saveState()).toByteArray()); - instList.initialLoad("instances"); - ui->instanceView->setModel(&instList); + instList.loadList(); } MainWindow::~MainWindow() @@ -67,7 +68,7 @@ void MainWindow::on_actionViewInstanceFolder_triggered() void MainWindow::on_actionRefresh_triggered() { - instList.initialLoad("instances"); + instList.loadList(); } void MainWindow::on_actionViewCentralModsFolder_triggered() diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 28ca341ae..d286bd0e5 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -18,7 +18,7 @@ #include -#include "data/instancemodel.h" +#include "data/inst/instancelist.h" #include "data/loginresponse.h" namespace Ui @@ -70,7 +70,7 @@ private slots: private: Ui::MainWindow *ui; - InstanceModel instList; + InstanceList instList; }; #endif // MAINWINDOW_H From f71479ec33562c9a0ebbdb335bef5e2824a12710 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 20 Feb 2013 08:32:26 -0600 Subject: [PATCH 07/15] Added stdinstance plugin and a ton of plugin stuff. --- CMakeLists.txt | 15 +++- data/inst/instance.cpp | 55 ++++++++++++++ data/inst/instance.h | 45 ++++++++++++ data/inst/instancetype.h | 4 +- data/plugin/instancetypeplugin.h | 41 +++++++++++ data/plugin/pluginmanager.cpp | 96 +++++++++++++++++++++++++ data/plugin/pluginmanager.h | 71 ++++++++++++++++++ libinstance/CMakeLists.txt | 31 ++++++++ main.cpp | 10 ++- plugins/stdinstance/CMakeLists.txt | 31 ++++++++ plugins/stdinstance/stdinstance.cpp | 53 ++++++++++++++ plugins/stdinstance/stdinstance.h | 36 ++++++++++ plugins/stdinstance/stdinstance.json | 1 + plugins/stdinstance/stdinstancetype.cpp | 34 +++++++++ plugins/stdinstance/stdinstancetype.h | 38 ++++++++++ plugins/stdinstance/stdinstplugin.cpp | 27 +++++++ plugins/stdinstance/stdinstplugin.h | 33 +++++++++ 17 files changed, 614 insertions(+), 7 deletions(-) create mode 100644 data/plugin/instancetypeplugin.h create mode 100644 data/plugin/pluginmanager.cpp create mode 100644 data/plugin/pluginmanager.h create mode 100644 libinstance/CMakeLists.txt create mode 100644 plugins/stdinstance/CMakeLists.txt create mode 100644 plugins/stdinstance/stdinstance.cpp create mode 100644 plugins/stdinstance/stdinstance.h create mode 100644 plugins/stdinstance/stdinstance.json create mode 100644 plugins/stdinstance/stdinstancetype.cpp create mode 100644 plugins/stdinstance/stdinstancetype.h create mode 100644 plugins/stdinstance/stdinstplugin.cpp create mode 100644 plugins/stdinstance/stdinstplugin.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a01edccf3..5e8f7a90f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,8 +16,8 @@ ENDIF(${BIGENDIAN}) include_directories(hacks) #### Find the required Qt parts #### -find_package(Qt5Widgets) -find_package(Qt5Network) +find_package(Qt5Widgets REQUIRED) +find_package(Qt5Network REQUIRED) #find_package(Qt5Declarative) include_directories(${Qt5Widgets_INCLUDE_DIRS}) @@ -35,6 +35,10 @@ include_directories(patchlib) # add the java launcher add_subdirectory(launcher) +# Add the stdinstance plugin. +add_subdirectory(plugins/stdinstance) + + IF(APPLE) # assume clang 4.1.0+, add C++0x/C++11 stuff message(STATUS "Using APPLE CMAKE_CXX_FLAGS") @@ -108,6 +112,8 @@ data/inst/instancetype.cpp data/inst/instance.cpp data/inst/instancelist.cpp +data/plugin/pluginmanager.cpp + data/version/instversion.cpp data/version/instversionlist.cpp @@ -149,6 +155,9 @@ data/inst/instancetype.h data/inst/instance.h data/inst/instancelist.h +data/plugin/pluginmanager.h +data/plugin/instancetypeplugin.h + data/version/instversion.h data/version/instversionlist.h @@ -205,7 +214,7 @@ QT5_ADD_RESOURCES(MULTIMC_QRC multimc.qrc) add_executable(MultiMC MACOSX_BUNDLE WIN32 ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC}) qt5_use_modules(MultiMC Widgets Network) -target_link_libraries(MultiMC quazip patchlib ${MultiMC_LINK_ADDITIONAL_LIBS}) +target_link_libraries(MultiMC quazip patchlib stdinstance ${MultiMC_LINK_ADDITIONAL_LIBS}) add_dependencies(MultiMC MultiMCLauncher) diff --git a/data/inst/instance.cpp b/data/inst/instance.cpp index 8561ed9f3..5db0be209 100644 --- a/data/inst/instance.cpp +++ b/data/inst/instance.cpp @@ -44,6 +44,61 @@ InstanceList *Instance::instList() return NULL; } +QString Instance::minecraftDir() const +{ + QFileInfo mcDir(PathCombine(rootDir(), "minecraft")); + QFileInfo dotMCDir(PathCombine(rootDir(), ".minecraft")); + + if (dotMCDir.exists() && !mcDir.exists()) + { + return dotMCDir.path(); + } + else + { + return mcDir.path(); + } +} + +QString Instance::binDir() const +{ + return PathCombine(minecraftDir(), "bin"); +} + +QString Instance::savesDir() const +{ + return PathCombine(minecraftDir(), "saves"); +} + +QString Instance::mlModsDir() const +{ + return PathCombine(minecraftDir(), "mods"); +} + +QString Instance::coreModsDir() const +{ + return PathCombine(minecraftDir(), "coremods"); +} + +QString Instance::resourceDir() const +{ + return PathCombine(minecraftDir(), "resources"); +} + +QString Instance::screenshotsDir() const +{ + return PathCombine(minecraftDir(), "screenshots"); +} + +QString Instance::texturePacksDir() const +{ + return PathCombine(minecraftDir(), "texturepacks"); +} + +QString Instance::mcJar() const +{ + return PathCombine(binDir(), "minecraft.jar"); +} + QVariant Instance::getField(const QString &name, QVariant defVal) const { return config.get(name, defVal); diff --git a/data/inst/instance.h b/data/inst/instance.h index 56e9d0b89..035704b93 100644 --- a/data/inst/instance.h +++ b/data/inst/instance.h @@ -214,6 +214,51 @@ public: { setField("lastLaunchTime", val); } + ////// Directories ////// + //! Gets the path to the instance's minecraft folder. + QString minecraftDir() const; + + /*! + * \brief Gets the path to the instance's instance mods folder. + * This is the folder where the jar mods are kept. + */ + QString instModsDir() const; + + //! Gets the path to the instance's bin folder. + QString binDir() const; + + //! Gets the path to the instance's saves folder. + QString savesDir() const; + + //! Gets the path to the instance's mods folder. (.minecraft/mods) + QString mlModsDir() const; + + //! Gets the path to the instance's coremods folder. + QString coreModsDir() const; + + //! Gets the path to the instance's resources folder. + QString resourceDir() const; + + //! Gets the path to the instance's screenshots folder. + QString screenshotsDir() const; + + //! Gets the path to the instance's texture packs folder. + QString texturePacksDir() const; + + + ////// Files ////// + //! Gets the path to the instance's minecraft.jar + QString mcJar() const; + + //! Gets the path to the instance's mcbackup.jar. + QString mcBackup() const; + + //! Gets the path to the instance's config file. + QString configFile() const; + + //! Gets the path to the instance's modlist file. + QString modListFile() const; + ////// Settings ////// //// Java Settings //// diff --git a/data/inst/instancetype.h b/data/inst/instancetype.h index ec3f5b87b..bd22a17cc 100644 --- a/data/inst/instancetype.h +++ b/data/inst/instancetype.h @@ -37,9 +37,7 @@ public: friend class InstanceLoader; /*! - * \brief Gets the ID for this instance type. - * By default this is the name of the Instance class that this type - * creates, but this can be changed by overriding this function. + * \brief Gets the ID for this instance type. * The type ID should be unique as it is used to identify the type * of instances when they are loaded. * Changing this value at runtime results in undefined behavior. diff --git a/data/plugin/instancetypeplugin.h b/data/plugin/instancetypeplugin.h new file mode 100644 index 000000000..8e3febdb2 --- /dev/null +++ b/data/plugin/instancetypeplugin.h @@ -0,0 +1,41 @@ +/* Copyright 2013 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. + */ + +#ifndef INSTANCETYPEPLUGIN_H +#define INSTANCETYPEPLUGIN_H + +#include + +#include "data/inst/instancetype.h" + +/*! + * \brief Interface for plugins that want to provide custom instance types. + */ +class InstanceTypePlugin +{ +public: + /*! + * \brief Gets a QList containing the instance types that this plugin provides. + * These instance types are then registered with the InstanceLoader. + * The InstanceType objects should \e not be deleted by the plugin. Once they + * are registered, they belong to the InstanceLoader. + * \return A QList containing this plugin's instance types. + */ + virtual QList getInstanceTypes() = 0; +}; + +Q_DECLARE_INTERFACE(InstanceTypePlugin, "net.forkk.MultiMC.InstanceTypePlugin/0.1") + +#endif // INSTANCETYPEPLUGIN_H diff --git a/data/plugin/pluginmanager.cpp b/data/plugin/pluginmanager.cpp new file mode 100644 index 000000000..cd33b285f --- /dev/null +++ b/data/plugin/pluginmanager.cpp @@ -0,0 +1,96 @@ +/* Copyright 2013 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 "pluginmanager.h" + +#include +#include +#include + +#include + +#include "data/plugin/instancetypeplugin.h" + +PluginManager PluginManager::manager; + +PluginManager::PluginManager() : + QObject(NULL) +{ + +} + +bool PluginManager::loadPlugins(QString pluginDir) +{ + m_plugins.clear(); + + QDir dir(pluginDir); + QDirIterator iter(dir); + + while (iter.hasNext()) + { + QFileInfo pluginFile(dir.absoluteFilePath(iter.next())); + + if (pluginFile.exists() && pluginFile.isFile()) + { + QPluginLoader pluginLoader(pluginFile.absoluteFilePath()); + pluginLoader.load(); + QObject *plugin = pluginLoader.instance(); + if (plugin) + { + qDebug(QString("Loaded plugin %1."). + arg(pluginFile.baseName()).toUtf8()); + m_plugins.push_back(plugin); + } + else + { + qWarning(QString("Error loading plugin %1. Not a valid plugin."). + arg(pluginFile.baseName()).toUtf8()); + } + } + } + + return true; +} + +bool PluginManager::initInstanceTypes() +{ + for (int i = 0; i < m_plugins.count(); i++) + { + InstanceTypePlugin *plugin = qobject_cast(m_plugins[i]); + if (plugin) + { + QList instanceTypes = plugin->getInstanceTypes(); + + for (int i = 0; i < instanceTypes.count(); i++) + { + InstanceLoader::InstTypeError error = + InstanceLoader::loader.registerInstanceType(instanceTypes[i]); + switch (error) + { + case InstanceLoader::TypeIDExists: + qWarning(QString("Instance type %1 already registered."). + arg(instanceTypes[i]->typeID()).toUtf8()); + } + } + } + } + + return true; +} + +QObject *PluginManager::getPlugin(int index) +{ + return m_plugins[index]; +} diff --git a/data/plugin/pluginmanager.h b/data/plugin/pluginmanager.h new file mode 100644 index 000000000..8e2dba0da --- /dev/null +++ b/data/plugin/pluginmanager.h @@ -0,0 +1,71 @@ +/* Copyright 2013 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. + */ + +#ifndef PLUGINMANAGER_H +#define PLUGINMANAGER_H + +#include +#include +#include + +/*! + * \brief This class is a singleton that manages loading plugins. + */ +class PluginManager : public QObject +{ + Q_OBJECT +public: + /*! + * \brief Gets the plugin manager instance. + */ + static PluginManager &get() { return manager; } + + /*! + * \brief Loads plugins from the given directory. + * This function does \e not initialize the plugins. It simply loads their + * classes. Use the init functions to initialize the various plugin types. + * \param The directory to load plugins from. + * \return True if successful. False on failure. + */ + bool loadPlugins(QString pluginDir); + + /*! + * \brief Initializes the instance type plugins. + * \return True if successful. False on failure. + */ + bool initInstanceTypes(); + + /*! + * \brief Checks how many plugins are loaded. + * \return The number of plugins. + */ + int count() { return m_plugins.count(); } + + /*! + * \brief Gets the plugin at the given index. + * \param index The index of the plugin to get. + * \return The plugin at the given index. + */ + QObject *getPlugin(int index); + +private: + PluginManager(); + + QList m_plugins; + + static PluginManager manager; +}; + +#endif // PLUGINMANAGER_H diff --git a/libinstance/CMakeLists.txt b/libinstance/CMakeLists.txt new file mode 100644 index 000000000..503bda751 --- /dev/null +++ b/libinstance/CMakeLists.txt @@ -0,0 +1,31 @@ +project(stdinstance) + +ADD_DEFINITIONS(-DQT_PLUGIN) + +# Find Qt +find_package(Qt5Core REQUIRED) +find_package(Qt5Network REQUIRED) + +# Include Qt headers. +include_directories(${Qt5Base_INCLUDE_DIRS}) +include_directories(${Qt5Network_INCLUDE_DIRS}) + +# Include MultiMC's headers. +include_directories(../../) + +SET(STDINST_HEADERS +stdinstplugin.h +stdinstancetype.h +stdinstance.h +) + +SET(STDINST_SOURCES +stdinstplugin.cpp +stdinstancetype.cpp +stdinstance.cpp +) + +add_library(stdinstance SHARED ${STDINST_SOURCES} ${STDINST_HEADERS}) +set_target_properties(stdinstance PROPERTIES PREFIX "") +qt5_use_modules(stdinstance Core Network) +target_link_libraries(stdinstance quazip patchlib) diff --git a/main.cpp b/main.cpp index 6e840317c..29c11e875 100644 --- a/main.cpp +++ b/main.cpp @@ -18,9 +18,12 @@ #include #include "data/appsettings.h" - #include "data/loginresponse.h" +#include "data/plugin/pluginmanager.h" + +#include "util/pathutils.h" + int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -32,6 +35,11 @@ int main(int argc, char *argv[]) // Register meta types. qRegisterMetaType("LoginResponse"); + + // Initialize plugins. + PluginManager::get().loadPlugins(PathCombine(qApp->applicationDirPath(), "plugins")); + PluginManager::get().initInstanceTypes(); + MainWindow mainWin; mainWin.show(); diff --git a/plugins/stdinstance/CMakeLists.txt b/plugins/stdinstance/CMakeLists.txt new file mode 100644 index 000000000..503bda751 --- /dev/null +++ b/plugins/stdinstance/CMakeLists.txt @@ -0,0 +1,31 @@ +project(stdinstance) + +ADD_DEFINITIONS(-DQT_PLUGIN) + +# Find Qt +find_package(Qt5Core REQUIRED) +find_package(Qt5Network REQUIRED) + +# Include Qt headers. +include_directories(${Qt5Base_INCLUDE_DIRS}) +include_directories(${Qt5Network_INCLUDE_DIRS}) + +# Include MultiMC's headers. +include_directories(../../) + +SET(STDINST_HEADERS +stdinstplugin.h +stdinstancetype.h +stdinstance.h +) + +SET(STDINST_SOURCES +stdinstplugin.cpp +stdinstancetype.cpp +stdinstance.cpp +) + +add_library(stdinstance SHARED ${STDINST_SOURCES} ${STDINST_HEADERS}) +set_target_properties(stdinstance PROPERTIES PREFIX "") +qt5_use_modules(stdinstance Core Network) +target_link_libraries(stdinstance quazip patchlib) diff --git a/plugins/stdinstance/stdinstance.cpp b/plugins/stdinstance/stdinstance.cpp new file mode 100644 index 000000000..194909651 --- /dev/null +++ b/plugins/stdinstance/stdinstance.cpp @@ -0,0 +1,53 @@ +/* Copyright 2013 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 "stdinstance.h" + +#include + +#include + +StdInstance::StdInstance(const QString &rootDir, QObject *parent) : + Instance(rootDir, parent) +{ + +} + +bool StdInstance::shouldUpdateCurrentVersion() +{ + QFileInfo jar(mcJar()); + return jar.lastModified().toUTC().toMSecsSinceEpoch() != lastVersionUpdate(); +} + +void StdInstance::updateCurrentVersion(bool keepCurrent) +{ + QFileInfo jar(mcJar()); + + if(!jar.exists()) + { + setLastVersionUpdate(0); + setCurrentVersion("Unknown"); + return; + } + + qint64 time = jar.lastModified().toUTC().toMSecsSinceEpoch(); + + setLastVersionUpdate(time); + if (!keepCurrent) + { + QString newVersion = javautils::GetMinecraftJarVersion(jar.absoluteFilePath()); + setCurrentVersion(newVersion); + } +} diff --git a/plugins/stdinstance/stdinstance.h b/plugins/stdinstance/stdinstance.h new file mode 100644 index 000000000..17c03f15b --- /dev/null +++ b/plugins/stdinstance/stdinstance.h @@ -0,0 +1,36 @@ +/* Copyright 2013 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. + */ + +#ifndef STDINSTANCE_H +#define STDINSTANCE_H + +#include + +class StdInstance : public Instance +{ + Q_OBJECT +public: + explicit StdInstance(const QString &rootDir, QObject *parent = 0); + + virtual bool shouldUpdateCurrentVersion(); + + virtual void updateCurrentVersion(bool keepCurrent); + + ////// TIMESTAMPS ////// + virtual qint64 lastVersionUpdate() { return getField("lastVersionUpdate", 0).value(); } + virtual void setLastVersionUpdate(qint64 val) { setField("lastVersionUpdate", val); } +}; + +#endif // STDINSTANCE_H diff --git a/plugins/stdinstance/stdinstance.json b/plugins/stdinstance/stdinstance.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/plugins/stdinstance/stdinstance.json @@ -0,0 +1 @@ +{} diff --git a/plugins/stdinstance/stdinstancetype.cpp b/plugins/stdinstance/stdinstancetype.cpp new file mode 100644 index 000000000..3e9e00a0f --- /dev/null +++ b/plugins/stdinstance/stdinstancetype.cpp @@ -0,0 +1,34 @@ +/* Copyright 2013 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 "stdinstancetype.h" + +StdInstanceType::StdInstanceType(QObject *parent) : + InstanceType(parent) +{ + +} + +InstanceLoader::InstTypeError StdInstanceType::createInstance(Instance *inst, + const QString &instDir) const +{ + return InstanceLoader::NoError; +} + +InstanceLoader::InstTypeError StdInstanceType::loadInstance(Instance *inst, + const QString &instDir) const +{ + return InstanceLoader::NoError; +} diff --git a/plugins/stdinstance/stdinstancetype.h b/plugins/stdinstance/stdinstancetype.h new file mode 100644 index 000000000..9516aa801 --- /dev/null +++ b/plugins/stdinstance/stdinstancetype.h @@ -0,0 +1,38 @@ +/* Copyright 2013 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. + */ + +#ifndef STDINSTANCETYPE_H +#define STDINSTANCETYPE_H + +#include + +class StdInstanceType : public InstanceType +{ + Q_OBJECT +public: + explicit StdInstanceType(QObject *parent = 0); + + virtual QString typeID() const { return "net.forkk.MultiMC.StdInstance"; } + + virtual QString displayName() const { return "Standard Instance"; } + + virtual QString description() const { return "A standard Minecraft instance."; } + + virtual InstanceLoader::InstTypeError createInstance(Instance *inst, const QString &instDir) const; + + virtual InstanceLoader::InstTypeError loadInstance(Instance *inst, const QString &instDir) const; +}; + +#endif // STDINSTANCETYPE_H diff --git a/plugins/stdinstance/stdinstplugin.cpp b/plugins/stdinstance/stdinstplugin.cpp new file mode 100644 index 000000000..98e12ae0f --- /dev/null +++ b/plugins/stdinstance/stdinstplugin.cpp @@ -0,0 +1,27 @@ +/* Copyright 2013 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 "stdinstplugin.h" + +#include + +#include "stdinstancetype.h" + +QList StdInstPlugin::getInstanceTypes() +{ + QList types; + types.push_back(new StdInstanceType(this)); + return types; +} diff --git a/plugins/stdinstance/stdinstplugin.h b/plugins/stdinstance/stdinstplugin.h new file mode 100644 index 000000000..f44409bd5 --- /dev/null +++ b/plugins/stdinstance/stdinstplugin.h @@ -0,0 +1,33 @@ +/* Copyright 2013 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. + */ + +#ifndef STDINSTPLUGIN_H +#define STDINSTPLUGIN_H + +#include + +#include + +class StdInstPlugin : public QObject, InstanceTypePlugin +{ + Q_OBJECT + Q_INTERFACES(InstanceTypePlugin) + Q_PLUGIN_METADATA(IID "net.forkk.MultiMC.Plugins.StdInstance") + +public: + virtual QList getInstanceTypes(); +}; + +#endif // STDINSTPLUGIN_H From dd2e836b4cf4cfa043f9ea2911f58f1d22d4e282 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 20 Feb 2013 19:10:09 -0600 Subject: [PATCH 08/15] Split MultiMC up into a few separate libraries. Fixed plugin system. Tons of other stuff... --- CMakeLists.txt | 113 ++++++++---------- data/plugin/instancetypeplugin.h | 41 ------- data/plugin/pluginmanager.cpp | 87 ++++++++------ data/plugin/pluginmanager.h | 17 +-- gui/mainwindow.cpp | 16 ++- gui/mainwindow.h | 2 +- gui/settingsdialog.cpp | 2 +- libinstance/CMakeLists.txt | 50 +++++--- {data/inst => libinstance/include}/instance.h | 14 ++- .../include}/instancelist.h | 6 +- .../include}/instanceloader.h | 28 +++-- .../include/instancetypeinterface.h | 13 +- .../include}/instversion.h | 4 +- .../include}/instversionlist.h | 4 +- .../include/libinstance_config.h | 16 ++- {data/inst => libinstance/src}/instance.cpp | 10 +- .../inst => libinstance/src}/instancelist.cpp | 32 +++-- .../src}/instanceloader.cpp | 25 ++-- .../src}/instversion.cpp | 4 +- .../src}/instversionlist.cpp | 2 +- libsettings/CMakeLists.txt | 30 +++++ {data => libsettings/include}/appsettings.h | 21 ++-- .../include/libsettings_config.h | 24 ++-- {data => libsettings/src}/appsettings.cpp | 2 +- libutil/CMakeLists.txt | 38 ++++++ {util => libutil/include}/apputils.h | 0 {data => libutil/include}/inifile.h | 4 +- .../include/libutil_config.h | 18 +-- {util => libutil/include}/osutils.h | 3 - {util => libutil/include}/pathutils.h | 8 +- {data => libutil/include}/siglist.h | 0 {data => libutil/include}/siglist_impl.h | 0 {data => libutil/src}/inifile.cpp | 2 +- {util => libutil/src}/osutils.cpp | 8 +- {util => libutil/src}/pathutils.cpp | 2 +- main.cpp | 4 +- plugins/stdinstance/CMakeLists.txt | 28 ++++- plugins/stdinstance/stdinstance.cpp | 5 +- plugins/stdinstance/stdinstance.h | 2 +- plugins/stdinstance/stdinstance.json | 9 +- plugins/stdinstance/stdinstancetype.cpp | 2 +- plugins/stdinstance/stdinstancetype.h | 8 +- 42 files changed, 404 insertions(+), 300 deletions(-) delete mode 100644 data/plugin/instancetypeplugin.h rename {data/inst => libinstance/include}/instance.h (97%) rename {data/inst => libinstance/include}/instancelist.h (89%) rename {data/inst => libinstance/include}/instanceloader.h (87%) rename data/inst/instancetype.h => libinstance/include/instancetypeinterface.h (89%) rename {data/version => libinstance/include}/instversion.h (95%) rename {data/version => libinstance/include}/instversionlist.h (93%) rename data/inst/instancetype.cpp => libinstance/include/libinstance_config.h (70%) rename {data/inst => libinstance/src}/instance.cpp (93%) rename {data/inst => libinstance/src}/instancelist.cpp (80%) rename {data/inst => libinstance/src}/instanceloader.cpp (78%) rename {data/version => libinstance/src}/instversion.cpp (92%) rename {data/version => libinstance/src}/instversionlist.cpp (94%) create mode 100644 libsettings/CMakeLists.txt rename {data => libsettings/include}/appsettings.h (85%) rename plugins/stdinstance/stdinstplugin.h => libsettings/include/libsettings_config.h (62%) rename {data => libsettings/src}/appsettings.cpp (96%) create mode 100644 libutil/CMakeLists.txt rename {util => libutil/include}/apputils.h (100%) rename {data => libutil/include}/inifile.h (91%) rename plugins/stdinstance/stdinstplugin.cpp => libutil/include/libutil_config.h (72%) rename {util => libutil/include}/osutils.h (89%) rename {util => libutil/include}/pathutils.h (74%) rename {data => libutil/include}/siglist.h (100%) rename {data => libutil/include}/siglist_impl.h (100%) rename {data => libutil/src}/inifile.cpp (98%) rename {util => libutil/src}/osutils.cpp (78%) rename {util => libutil/src}/pathutils.cpp (97%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e8f7a90f..eea4ded54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(MultiMC) set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) #### Check for machine endianness #### INCLUDE(TestBigEndian) @@ -32,9 +33,22 @@ add_subdirectory(quazip) add_subdirectory(patchlib) include_directories(patchlib) -# add the java launcher +# Add the java launcher add_subdirectory(launcher) + +# Add the util library. +add_subdirectory(libutil) +include_directories(${LIBMMCUTIL_INCLUDE_DIR}) + +# Add the settings library. +add_subdirectory(libsettings) +include_directories(${LIBMMCSETTINGS_INCLUDE_DIR}) + +# Add the instance library. +add_subdirectory(libinstance) +include_directories(${LIBMMCINST_INCLUDE_DIR}) + # Add the stdinstance plugin. add_subdirectory(plugins/stdinstance) @@ -97,43 +111,6 @@ message(STATUS "Job URL: ${MultiMC_JOB_URL}") configure_file("${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_BINARY_DIR}/config.h") - -SET(MULTIMC_SOURCES -main.cpp - -data/appsettings.cpp -data/inifile.cpp -data/version.cpp -data/userinfo.cpp -data/loginresponse.cpp - -data/inst/instanceloader.cpp -data/inst/instancetype.cpp -data/inst/instance.cpp -data/inst/instancelist.cpp - -data/plugin/pluginmanager.cpp - -data/version/instversion.cpp -data/version/instversionlist.cpp - -gui/mainwindow.cpp -gui/modeditwindow.cpp -gui/settingsdialog.cpp -gui/newinstancedialog.cpp -gui/logindialog.cpp -gui/taskdialog.cpp - -util/pathutils.cpp -util/osutils.cpp - -java/javautils.cpp -java/annotations.cpp - -tasks/task.cpp -tasks/logintask.cpp -) - SET(MULTIMC_HEADERS gui/mainwindow.h gui/modeditwindow.h @@ -142,28 +119,11 @@ gui/newinstancedialog.h gui/logindialog.h gui/taskdialog.h -data/appsettings.h -data/inifile.h data/version.h data/userinfo.h data/loginresponse.h -data/siglist.h -data/siglist_impl.h - -data/inst/instanceloader.h -data/inst/instancetype.h -data/inst/instance.h -data/inst/instancelist.h data/plugin/pluginmanager.h -data/plugin/instancetypeplugin.h - -data/version/instversion.h -data/version/instversionlist.h - -util/apputils.h -util/pathutils.h -util/osutils.h multimc_pragma.h @@ -179,6 +139,29 @@ tasks/task.h tasks/logintask.h ) +SET(MULTIMC_SOURCES +main.cpp + +data/version.cpp +data/userinfo.cpp +data/loginresponse.cpp + +data/plugin/pluginmanager.cpp + +gui/mainwindow.cpp +gui/modeditwindow.cpp +gui/settingsdialog.cpp +gui/newinstancedialog.cpp +gui/logindialog.cpp +gui/taskdialog.cpp + +java/javautils.cpp +java/annotations.cpp + +tasks/task.cpp +tasks/logintask.cpp +) + SET(MULTIMC5_UIS gui/mainwindow.ui gui/modeditwindow.ui @@ -214,8 +197,10 @@ QT5_ADD_RESOURCES(MULTIMC_QRC multimc.qrc) add_executable(MultiMC MACOSX_BUNDLE WIN32 ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC}) qt5_use_modules(MultiMC Widgets Network) -target_link_libraries(MultiMC quazip patchlib stdinstance ${MultiMC_LINK_ADDITIONAL_LIBS}) -add_dependencies(MultiMC MultiMCLauncher) +target_link_libraries(MultiMC quazip patchlib +libmmcutil libmmcsettings libmmcinst +${MultiMC_LINK_ADDITIONAL_LIBS}) +add_dependencies(MultiMC MultiMCLauncher libmmcutil libmmcsettings libmmcinst) ################ Dirs ################ @@ -225,9 +210,9 @@ SET(QTCONF_DEST_DIR bin) SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC") IF(WIN32) - #SET(PLUGIN_DEST_DIR .) - #SET(QTCONF_DEST_DIR .) - SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC.exe") + SET(PLUGIN_DEST_DIR .) + SET(QTCONF_DEST_DIR .) + SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.exe") ENDIF() IF(APPLE) SET(PLUGIN_DEST_DIR MultiMC.app/Contents/MacOS) @@ -255,7 +240,7 @@ ENDIF(APPLE) IF(WIN32) INSTALL(TARGETS MultiMC BUNDLE DESTINATION . COMPONENT Runtime - RUNTIME DESTINATION bin COMPONENT Runtime + RUNTIME DESTINATION . COMPONENT Runtime ) ENDIF() IF(UNIX) @@ -287,7 +272,11 @@ INSTALL(CODE " # Dirs to look for dependencies. -SET(DIRS ${QT_LIBRARY_DIRS}) +SET(DIRS "${QT_LIBRARY_DIRS} +${CMAKE_BINARY_DIR}/libutil +${CMAKE_BINARY_DIR}/libsettings +${CMAKE_BINARY_DIR}/libinstance") +message(STATUS "${DIRS}") INSTALL(CODE " file(GLOB_RECURSE QTPLUGINS diff --git a/data/plugin/instancetypeplugin.h b/data/plugin/instancetypeplugin.h deleted file mode 100644 index 8e3febdb2..000000000 --- a/data/plugin/instancetypeplugin.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright 2013 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. - */ - -#ifndef INSTANCETYPEPLUGIN_H -#define INSTANCETYPEPLUGIN_H - -#include - -#include "data/inst/instancetype.h" - -/*! - * \brief Interface for plugins that want to provide custom instance types. - */ -class InstanceTypePlugin -{ -public: - /*! - * \brief Gets a QList containing the instance types that this plugin provides. - * These instance types are then registered with the InstanceLoader. - * The InstanceType objects should \e not be deleted by the plugin. Once they - * are registered, they belong to the InstanceLoader. - * \return A QList containing this plugin's instance types. - */ - virtual QList getInstanceTypes() = 0; -}; - -Q_DECLARE_INTERFACE(InstanceTypePlugin, "net.forkk.MultiMC.InstanceTypePlugin/0.1") - -#endif // INSTANCETYPEPLUGIN_H diff --git a/data/plugin/pluginmanager.cpp b/data/plugin/pluginmanager.cpp index cd33b285f..2f0662936 100644 --- a/data/plugin/pluginmanager.cpp +++ b/data/plugin/pluginmanager.cpp @@ -18,10 +18,17 @@ #include #include #include +#include + +#include #include -#include "data/plugin/instancetypeplugin.h" +#include "instancetypeinterface.h" + +// MultiMC's API version. This must match the "api" field in each plugin's +// metadata or MultiMC won't consider them valid MultiMC plugin. +#define MMC_API_VERSION "MultiMC5-API-1" PluginManager PluginManager::manager; @@ -33,8 +40,16 @@ PluginManager::PluginManager() : bool PluginManager::loadPlugins(QString pluginDir) { + // Delete the loaded plugins and clear the list. + for (int i = 0; i < m_plugins.count(); i++) + { + delete m_plugins[i]; + } m_plugins.clear(); + qDebug(QString("Loading plugins from directory: %1"). + arg(pluginDir).toUtf8()); + QDir dir(pluginDir); QDirIterator iter(dir); @@ -44,53 +59,47 @@ bool PluginManager::loadPlugins(QString pluginDir) if (pluginFile.exists() && pluginFile.isFile()) { - QPluginLoader pluginLoader(pluginFile.absoluteFilePath()); - pluginLoader.load(); - QObject *plugin = pluginLoader.instance(); - if (plugin) - { - qDebug(QString("Loaded plugin %1."). - arg(pluginFile.baseName()).toUtf8()); - m_plugins.push_back(plugin); - } - else - { - qWarning(QString("Error loading plugin %1. Not a valid plugin."). - arg(pluginFile.baseName()).toUtf8()); - } - } - } - - return true; -} - -bool PluginManager::initInstanceTypes() -{ - for (int i = 0; i < m_plugins.count(); i++) - { - InstanceTypePlugin *plugin = qobject_cast(m_plugins[i]); - if (plugin) - { - QList instanceTypes = plugin->getInstanceTypes(); + qDebug(QString("Attempting to load plugin: %1"). + arg(pluginFile.canonicalFilePath()).toUtf8()); - for (int i = 0; i < instanceTypes.count(); i++) + QPluginLoader *pluginLoader = new QPluginLoader(pluginFile.absoluteFilePath()); + + QJsonObject pluginInfo = pluginLoader->metaData(); + QJsonObject pluginMetadata = pluginInfo.value("MetaData").toObject(); + + if (pluginMetadata.value("api").toString("") != MMC_API_VERSION) { - InstanceLoader::InstTypeError error = - InstanceLoader::loader.registerInstanceType(instanceTypes[i]); - switch (error) - { - case InstanceLoader::TypeIDExists: - qWarning(QString("Instance type %1 already registered."). - arg(instanceTypes[i]->typeID()).toUtf8()); - } + // If "api" is not specified, it's not a MultiMC plugin. + qDebug(QString("Not loading plugin %1. Not a valid MultiMC plugin. " + "API: %2"). + arg(pluginFile.canonicalFilePath(), pluginMetadata.value("api").toString("")).toUtf8()); + continue; } + + qDebug(QString("Loaded plugin: %1"). + arg(pluginInfo.value("IID").toString()).toUtf8()); + m_plugins.push_back(pluginLoader); } } return true; } -QObject *PluginManager::getPlugin(int index) +QPluginLoader *PluginManager::getPlugin(int index) { return m_plugins[index]; } + +void PluginManager::initInstanceTypes() +{ + for (int i = 0; i < m_plugins.count(); i++) + { + InstanceTypeInterface *instType = qobject_cast(m_plugins[i]->instance()); + + if (instType) + { + // TODO: Handle errors + InstanceLoader::get().registerInstanceType(instType); + } + } +} diff --git a/data/plugin/pluginmanager.h b/data/plugin/pluginmanager.h index 8e2dba0da..b93fd6d27 100644 --- a/data/plugin/pluginmanager.h +++ b/data/plugin/pluginmanager.h @@ -41,12 +41,6 @@ public: */ bool loadPlugins(QString pluginDir); - /*! - * \brief Initializes the instance type plugins. - * \return True if successful. False on failure. - */ - bool initInstanceTypes(); - /*! * \brief Checks how many plugins are loaded. * \return The number of plugins. @@ -58,12 +52,19 @@ public: * \param index The index of the plugin to get. * \return The plugin at the given index. */ - QObject *getPlugin(int index); + QPluginLoader *getPlugin(int index); + + /*! + * \brief Initializes and registers all the instance types. + * This is done by going through the plugin list and registering all of the + * plugins that derive from the InstanceTypeInterface with the InstanceLoader. + */ + void initInstanceTypes(); private: PluginManager(); - QList m_plugins; + QList m_plugins; static PluginManager manager; }; diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index d19d69dcf..19ff21085 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -21,20 +21,25 @@ #include #include +#include -#include "util/osutils.h" +#include "osutils.h" #include "gui/settingsdialog.h" #include "gui/newinstancedialog.h" #include "gui/logindialog.h" #include "gui/taskdialog.h" -#include "data/inst/instancelist.h" -#include "data/appsettings.h" +#include "instancelist.h" +#include "appsettings.h" #include "data/version.h" #include "tasks/logintask.h" +// Opens the given file in the default application. +// TODO: Move this somewhere. +void openInDefaultProgram(QString filename); + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), @@ -156,3 +161,8 @@ void MainWindow::onLoginComplete(LoginResponse response) QString("Logged in as %1 with session ID %2."). arg(response.getUsername(), response.getSessionID())); } + +void openInDefaultProgram(QString filename) +{ + QDesktopServices::openUrl("file:///" + QFileInfo(filename).absolutePath()); +} diff --git a/gui/mainwindow.h b/gui/mainwindow.h index d286bd0e5..591d06326 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -18,7 +18,7 @@ #include -#include "data/inst/instancelist.h" +#include "instancelist.h" #include "data/loginresponse.h" namespace Ui diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index ab4d18ee9..b3c423803 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -16,7 +16,7 @@ #include "settingsdialog.h" #include "ui_settingsdialog.h" -#include "data/appsettings.h" +#include "appsettings.h" #include #include diff --git a/libinstance/CMakeLists.txt b/libinstance/CMakeLists.txt index 503bda751..d0a9aa085 100644 --- a/libinstance/CMakeLists.txt +++ b/libinstance/CMakeLists.txt @@ -1,31 +1,47 @@ -project(stdinstance) +project(libmmcinst) -ADD_DEFINITIONS(-DQT_PLUGIN) +set(CMAKE_AUTOMOC ON) # Find Qt find_package(Qt5Core REQUIRED) -find_package(Qt5Network REQUIRED) # Include Qt headers. include_directories(${Qt5Base_INCLUDE_DIRS}) include_directories(${Qt5Network_INCLUDE_DIRS}) -# Include MultiMC's headers. -include_directories(../../) +# Include utility library. +include_directories(${CMAKE_SOURCE_DIR}/libutil/include) -SET(STDINST_HEADERS -stdinstplugin.h -stdinstancetype.h -stdinstance.h +# Include utility library. +include_directories(${CMAKE_SOURCE_DIR}/libsettings/include) + +SET(LIBINST_HEADERS +include/libinstance_config.h + +include/instancetypeinterface.h + +include/instance.h +include/instancelist.h +include/instanceloader.h + +include/instversion.h +include/instversionlist.h ) -SET(STDINST_SOURCES -stdinstplugin.cpp -stdinstancetype.cpp -stdinstance.cpp +SET(LIBINST_SOURCES +src/instance.cpp +src/instancelist.cpp +src/instanceloader.cpp + +src/instversion.cpp +src/instversionlist.cpp ) -add_library(stdinstance SHARED ${STDINST_SOURCES} ${STDINST_HEADERS}) -set_target_properties(stdinstance PROPERTIES PREFIX "") -qt5_use_modules(stdinstance Core Network) -target_link_libraries(stdinstance quazip patchlib) +# Set the include dir path. +SET(LIBMMCINST_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE) + +add_definitions(-DLIBMMCINST_LIBRARY) + +add_library(libmmcinst SHARED ${LIBINST_SOURCES} ${LIBINST_HEADERS}) +qt5_use_modules(libmmcinst Core) +target_link_libraries(libmmcinst libmmcutil libmmcsettings) diff --git a/data/inst/instance.h b/libinstance/include/instance.h similarity index 97% rename from data/inst/instance.h rename to libinstance/include/instance.h index 035704b93..7b3c001db 100644 --- a/data/inst/instance.h +++ b/libinstance/include/instance.h @@ -19,8 +19,10 @@ #include #include -#include "data/appsettings.h" -#include "data/inifile.h" +#include "appsettings.h" +#include "inifile.h" + +#include "libinstance_config.h" #define DEFINE_OVERRIDDEN_SETTING_ADVANCED(funcName, cfgEntryName, typeName) \ typeName get ## funcName() const { return getField(cfgEntryName, settings->get ## funcName()).value(); } @@ -38,7 +40,7 @@ class InstanceList; * To create a new instance type, create a new class inheriting from this class * and implement the pure virtual functions. */ -class Instance : public SettingsBase +class LIBMMCINST_EXPORT Instance : public SettingsBase { Q_OBJECT public: @@ -62,13 +64,13 @@ public: * * \return The instance's ID. */ - virtual QString id(); + virtual QString id() const; /*! * \brief Gets the path to the instance's root directory. * \return The path to the instance's root directory. */ - virtual QString rootDir(); + virtual QString rootDir() const; /*! * \brief Gets the instance list that this instance is a part of. @@ -76,7 +78,7 @@ public: * (the parent is not an InstanceList). * \return A pointer to the InstanceList containing this instance. */ - virtual InstanceList *instList(); + virtual InstanceList *instList() const; //////// FIELDS AND SETTINGS //////// diff --git a/data/inst/instancelist.h b/libinstance/include/instancelist.h similarity index 89% rename from data/inst/instancelist.h rename to libinstance/include/instancelist.h index c43c4cc08..f6be815c9 100644 --- a/data/inst/instancelist.h +++ b/libinstance/include/instancelist.h @@ -20,11 +20,13 @@ #include -#include "data/siglist.h" +#include "siglist.h" + +#include "libinstance_config.h" class Instance; -class InstanceList : public QObject, public SigList> +class LIBMMCINST_EXPORT InstanceList : public QObject, public SigList> { Q_OBJECT public: diff --git a/data/inst/instanceloader.h b/libinstance/include/instanceloader.h similarity index 87% rename from data/inst/instanceloader.h rename to libinstance/include/instanceloader.h index 60c4e998b..396966392 100644 --- a/data/inst/instanceloader.h +++ b/libinstance/include/instanceloader.h @@ -20,21 +20,26 @@ #include #include -class InstanceType; +#include "libinstance_config.h" + +class InstanceTypeInterface; class Instance; -typedef QList InstTypeList; +typedef QList InstTypeList; /*! * \brief The InstanceLoader is a singleton that manages all of the instance types and handles loading and creating instances. * Instance types are registered with the instance loader through its registerInstType() function. * Creating instances is done through the InstanceLoader's createInstance() function. This function takes */ -class InstanceLoader : public QObject +class LIBMMCINST_EXPORT InstanceLoader : public QObject { Q_OBJECT public: - static InstanceLoader loader; + /*! + * \brief Gets a reference to the instance loader. + */ + static InstanceLoader &get() { return loader; } /*! * \brief Error codes returned by functions in the InstanceLoader and InstanceType classes. @@ -62,15 +67,12 @@ public: /*! * \brief Registers the given InstanceType with the instance loader. - * This causes the instance loader to take ownership of the given - * instance type (meaning the instance type's parent will be set to - * the instance loader). * * \param type The InstanceType to register. * \return An InstTypeError error code. * - TypeIDExists if the given type's is already registered to another instance type. */ - InstTypeError registerInstanceType(InstanceType *type); + InstTypeError registerInstanceType(InstanceTypeInterface *type); /*! * \brief Creates an instance with the given type and stores it in inst. @@ -82,7 +84,7 @@ public: * - TypeNotRegistered if the given type is not registered with the InstanceLoader. * - InstExists if the given instance directory is already an instance. */ - InstTypeError createInstance(Instance *inst, const InstanceType *type, const QString &instDir); + InstTypeError createInstance(Instance *inst, const InstanceTypeInterface *type, const QString &instDir); /*! * \brief Loads an instance from the given directory. @@ -95,7 +97,7 @@ public: * - NotAnInstance if the given instance directory isn't a valid instance. * - WrongInstType if the given instance directory's type isn't the same as the given type. */ - InstTypeError loadInstance(Instance *inst, const InstanceType *type, const QString &instDir); + InstTypeError loadInstance(Instance *inst, const InstanceTypeInterface *type, const QString &instDir); /*! * \brief Loads an instance from the given directory. @@ -115,7 +117,7 @@ public: * \param id The ID of the type to find. * \return The type with the given ID. NULL if none were found. */ - const InstanceType *findType(const QString &id); + const InstanceTypeInterface *findType(const QString &id); /*! * \brief Gets a list of the registered instance types. @@ -127,7 +129,9 @@ public: private: InstanceLoader(); - QMap m_typeMap; + QMap m_typeMap; + + static InstanceLoader loader; }; #endif // INSTANCELOADER_H diff --git a/data/inst/instancetype.h b/libinstance/include/instancetypeinterface.h similarity index 89% rename from data/inst/instancetype.h rename to libinstance/include/instancetypeinterface.h index bd22a17cc..a061b9d2e 100644 --- a/data/inst/instancetype.h +++ b/libinstance/include/instancetypeinterface.h @@ -20,20 +20,21 @@ #include "instanceloader.h" +//! The InstanceTypeInterface's interface ID. +#define InstanceTypeInterface_IID "net.forkk.MultiMC.InstanceTypeInterface/0.1" + /*! - * \brief The InstanceType class is a base class for all instance types. + * \brief The InstanceType class is an interface for all instance types. + * InstanceTypes are usually provided by plugins. * It handles loading and creating instances of a certain type. There should be * one of these for each type of instance and they should be registered with the * InstanceLoader. * To create an instance, the InstanceLoader calls the type's createInstance() * function. Loading is done through the loadInstance() function. */ -class InstanceType : public QObject +class InstanceTypeInterface { - Q_OBJECT public: - explicit InstanceType(QObject *parent = 0); - friend class InstanceLoader; /*! @@ -80,4 +81,6 @@ protected: virtual InstanceLoader::InstTypeError loadInstance(Instance *inst, const QString &instDir) const = 0; }; +Q_DECLARE_INTERFACE(InstanceTypeInterface, InstanceTypeInterface_IID) + #endif // INSTANCETYPE_H diff --git a/data/version/instversion.h b/libinstance/include/instversion.h similarity index 95% rename from data/version/instversion.h rename to libinstance/include/instversion.h index 361563fd7..c505c5a3d 100644 --- a/data/version/instversion.h +++ b/libinstance/include/instversion.h @@ -18,9 +18,11 @@ #include +#include "libinstance_config.h" + class InstVersionList; -class InstVersion : public QObject +class LIBMMCINST_EXPORT InstVersion : public QObject { Q_OBJECT public: diff --git a/data/version/instversionlist.h b/libinstance/include/instversionlist.h similarity index 93% rename from data/version/instversionlist.h rename to libinstance/include/instversionlist.h index f79bc1b03..2cd9ed1e4 100644 --- a/data/version/instversionlist.h +++ b/libinstance/include/instversionlist.h @@ -18,13 +18,15 @@ #include +#include "libinstance_config.h" + class InstVersion; // Class that each instance type's version list derives from. Version lists are // the lists that keep track of the available game versions for that instance. // This list will not be loaded on startup. It will be loaded when the list's // load function is called. -class InstVersionList : public QObject +class LIBMMCINST_EXPORT InstVersionList : public QObject { Q_OBJECT public: diff --git a/data/inst/instancetype.cpp b/libinstance/include/libinstance_config.h similarity index 70% rename from data/inst/instancetype.cpp rename to libinstance/include/libinstance_config.h index 4f27542dd..2e6dc8847 100644 --- a/data/inst/instancetype.cpp +++ b/libinstance/include/libinstance_config.h @@ -13,9 +13,15 @@ * limitations under the License. */ -#include "instancetype.h" +//#ifndef LIBINSTANCE_CONFIG_H +//#define LIBINSTANCE_CONFIG_H -InstanceType::InstanceType(QObject *parent) : - QObject(parent) -{ -} +#include + +#ifdef LIBMMCINST_LIBRARY +# define LIBMMCINST_EXPORT Q_DECL_EXPORT +#else +# define LIBMMCINST_EXPORT Q_DECL_IMPORT +#endif + +//#endif // LIBINSTANCE_CONFIG_H diff --git a/data/inst/instance.cpp b/libinstance/src/instance.cpp similarity index 93% rename from data/inst/instance.cpp rename to libinstance/src/instance.cpp index 5db0be209..c79c02138 100644 --- a/data/inst/instance.cpp +++ b/libinstance/src/instance.cpp @@ -13,11 +13,11 @@ * limitations under the License. */ -#include "instance.h" +#include "include/instance.h" #include -#include "util/pathutils.h" +#include "pathutils.h" Instance::Instance(const QString &rootDir, QObject *parent) : SettingsBase(parent) @@ -26,17 +26,17 @@ Instance::Instance(const QString &rootDir, QObject *parent) : config.loadFile(PathCombine(rootDir, "instance.cfg")); } -QString Instance::id() +QString Instance::id() const { return QFileInfo(rootDir()).baseName(); } -QString Instance::rootDir() +QString Instance::rootDir() const { return m_rootDir; } -InstanceList *Instance::instList() +InstanceList *Instance::instList() const { if (parent()->inherits("InstanceList")) return (InstanceList *)parent(); diff --git a/data/inst/instancelist.cpp b/libinstance/src/instancelist.cpp similarity index 80% rename from data/inst/instancelist.cpp rename to libinstance/src/instancelist.cpp index cbb89f051..15f79d05d 100644 --- a/data/inst/instancelist.cpp +++ b/libinstance/src/instancelist.cpp @@ -13,18 +13,18 @@ * limitations under the License. */ -#include "instancelist.h" +#include "include/instancelist.h" -#include "data/siglist_impl.h" +#include "siglist_impl.h" #include #include #include -#include "instance.h" -#include "instanceloader.h" +#include "include/instance.h" +#include "include/instanceloader.h" -#include "util/pathutils.h" +#include "pathutils.h" InstanceList::InstanceList(const QString &instDir, QObject *parent) : @@ -44,16 +44,11 @@ InstanceList::InstListError InstanceList::loadList() if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) { QSharedPointer inst; - InstanceLoader::InstTypeError error = InstanceLoader::loader. + InstanceLoader::InstTypeError error = InstanceLoader::get(). loadInstance(inst.data(), subDir); - if (inst.data() && error == InstanceLoader::NoError) - { - qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8()); - inst->setParent(this); - append(QSharedPointer(inst)); - } - else if (error != InstanceLoader::NotAnInstance) + if (error != InstanceLoader::NoError && + error != InstanceLoader::NotAnInstance) { QString errorMsg = QString("Failed to load instance %1: "). arg(QFileInfo(subDir).baseName()).toUtf8(); @@ -63,6 +58,11 @@ InstanceList::InstListError InstanceList::loadList() case InstanceLoader::TypeNotRegistered: errorMsg += "Instance type not found."; break; + + default: + errorMsg += QString("Unknown instance loader error %1"). + arg(error); + break; } qDebug(errorMsg.toUtf8()); } @@ -71,6 +71,12 @@ InstanceList::InstListError InstanceList::loadList() qDebug(QString("Error loading instance %1. Instance loader returned null."). arg(QFileInfo(subDir).baseName()).toUtf8()); } + else + { + qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8()); + inst->setParent(this); + append(QSharedPointer(inst)); + } } } diff --git a/data/inst/instanceloader.cpp b/libinstance/src/instanceloader.cpp similarity index 78% rename from data/inst/instanceloader.cpp rename to libinstance/src/instanceloader.cpp index e80a0e9e7..eff9d56ee 100644 --- a/data/inst/instanceloader.cpp +++ b/libinstance/src/instanceloader.cpp @@ -13,15 +13,15 @@ * limitations under the License. */ -#include "instanceloader.h" +#include "include/instanceloader.h" #include -#include "instancetype.h" +#include "include/instancetypeinterface.h" -#include "data/inifile.h" +#include "inifile.h" -#include "util/pathutils.h" +#include "pathutils.h" InstanceLoader InstanceLoader::loader; @@ -32,22 +32,25 @@ InstanceLoader::InstanceLoader() : } -InstanceLoader::InstTypeError InstanceLoader::registerInstanceType(InstanceType *type) +InstanceLoader::InstTypeError InstanceLoader::registerInstanceType(InstanceTypeInterface *type) { // Check to see if the type ID exists. if (m_typeMap.contains(type->typeID())) return TypeIDExists; // Set the parent to this. - type->setParent(this); + // ((QObject *)type)->setParent(this); // Add it to the map. m_typeMap.insert(type->typeID(), type); + + qDebug(QString("Registered instance type %1."). + arg(type->typeID()).toUtf8()); return NoError; } InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *inst, - const InstanceType *type, + const InstanceTypeInterface *type, const QString &instDir) { // Check if the type is registered. @@ -59,7 +62,7 @@ InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *inst, } InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, - const InstanceType *type, + const InstanceTypeInterface *type, const QString &instDir) { // Check if the type is registered. @@ -79,13 +82,13 @@ InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, INIFile ini; ini.loadFile(instConfig.path()); - QString typeName = ini.get("type", "StdInstance").toString(); - const InstanceType *type = findType(typeName); + QString typeName = ini.get("type", "net.forkk.MultiMC.StdInstance").toString(); + const InstanceTypeInterface *type = findType(typeName); return loadInstance(inst, type, instDir); } -const InstanceType *InstanceLoader::findType(const QString &id) +const InstanceTypeInterface *InstanceLoader::findType(const QString &id) { if (!m_typeMap.contains(id)) return NULL; diff --git a/data/version/instversion.cpp b/libinstance/src/instversion.cpp similarity index 92% rename from data/version/instversion.cpp rename to libinstance/src/instversion.cpp index 1493153af..cedb61df3 100644 --- a/data/version/instversion.cpp +++ b/libinstance/src/instversion.cpp @@ -13,8 +13,8 @@ * limitations under the License. */ -#include "instversion.h" -#include "instversionlist.h" +#include "include/instversion.h" +#include "include/instversionlist.h" InstVersion::InstVersion(InstVersionList *parent) : QObject(parent) diff --git a/data/version/instversionlist.cpp b/libinstance/src/instversionlist.cpp similarity index 94% rename from data/version/instversionlist.cpp rename to libinstance/src/instversionlist.cpp index ab57f94c9..e171cfa5a 100644 --- a/data/version/instversionlist.cpp +++ b/libinstance/src/instversionlist.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "instversionlist.h" +#include "include/instversionlist.h" InstVersionList::InstVersionList() : QObject(NULL) diff --git a/libsettings/CMakeLists.txt b/libsettings/CMakeLists.txt new file mode 100644 index 000000000..2cf723653 --- /dev/null +++ b/libsettings/CMakeLists.txt @@ -0,0 +1,30 @@ +project(libmmcsettings) + +# Find Qt +find_package(Qt5Core REQUIRED) + +# Include Qt headers. +include_directories(${Qt5Base_INCLUDE_DIRS}) +include_directories(${Qt5Network_INCLUDE_DIRS}) + +# Include utils library headers. +include_directories(${CMAKE_SOURCE_DIR}/libutil/include) + +SET(LIBSETTINGS_HEADERS +include/libsettings_config.h + +include/appsettings.h +) + +SET(LIBSETTINGS_SOURCES +src/appsettings.cpp +) + +# Set the include dir path. +SET(LIBMMCSETTINGS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE) + +add_definitions(-DLIBMMCSETTINGS_LIBRARY) + +add_library(libmmcsettings SHARED ${LIBSETTINGS_SOURCES} ${LIBSETTINGS_HEADERS}) +qt5_use_modules(libmmcsettings Core) +target_link_libraries(libmmcsettings libmmcutil) diff --git a/data/appsettings.h b/libsettings/include/appsettings.h similarity index 85% rename from data/appsettings.h rename to libsettings/include/appsettings.h index 8a786db02..795156185 100644 --- a/data/appsettings.h +++ b/libsettings/include/appsettings.h @@ -18,11 +18,13 @@ #include #include -#include +//#include #include -#include "util/apputils.h" -#include "util/osutils.h" +#include +#include + +#include "libsettings_config.h" #if WINDOWS #define JPATHKEY "JavaPathWindows" @@ -40,7 +42,7 @@ DEFINE_SETTING_ADVANCED(name, STR_VAL(name), valType, defVal) -class SettingsBase : public QObject +class LIBMMCSETTINGS_EXPORT SettingsBase : public QObject { Q_OBJECT public: @@ -64,9 +66,10 @@ public: DEFINE_SETTING(InstanceToolbarPosition, QPoint, QPoint()) // Console Colors - DEFINE_SETTING(SysMessageColor, QColor, QColor(Qt::blue)) - DEFINE_SETTING(StdOutColor, QColor, QColor(Qt::black)) - DEFINE_SETTING(StdErrColor, QColor, QColor(Qt::red)) + // Currently commented out because QColor is a part of QtGUI +// DEFINE_SETTING(SysMessageColor, QColor, QColor(Qt::blue)) +// DEFINE_SETTING(StdOutColor, QColor, QColor(Qt::black)) +// DEFINE_SETTING(StdErrColor, QColor, QColor(Qt::red)) // Window Size DEFINE_SETTING(LaunchCompatMode, bool, false) @@ -93,7 +96,7 @@ public: virtual void setValue(const QString& name, QVariant val) = 0; }; -class AppSettings : public SettingsBase +class LIBMMCSETTINGS_EXPORT AppSettings : public SettingsBase { Q_OBJECT public: @@ -111,6 +114,6 @@ protected: #undef DEFINE_SETTING_ADVANCED #undef DEFINE_SETTING -extern AppSettings* settings; +LIBMMCSETTINGS_EXPORT extern AppSettings* settings; #endif // APPSETTINGS_H diff --git a/plugins/stdinstance/stdinstplugin.h b/libsettings/include/libsettings_config.h similarity index 62% rename from plugins/stdinstance/stdinstplugin.h rename to libsettings/include/libsettings_config.h index f44409bd5..05df5bfae 100644 --- a/plugins/stdinstance/stdinstplugin.h +++ b/libsettings/include/libsettings_config.h @@ -13,21 +13,15 @@ * limitations under the License. */ -#ifndef STDINSTPLUGIN_H -#define STDINSTPLUGIN_H +#ifndef LIBINSTANCE_CONFIG_H +#define LIBINSTANCE_CONFIG_H -#include +#include -#include +#ifdef LIBMMCSETTINGS_LIBRARY +# define LIBMMCSETTINGS_EXPORT Q_DECL_EXPORT +#else +# define LIBMMCSETTINGS_EXPORT Q_DECL_IMPORT +#endif -class StdInstPlugin : public QObject, InstanceTypePlugin -{ - Q_OBJECT - Q_INTERFACES(InstanceTypePlugin) - Q_PLUGIN_METADATA(IID "net.forkk.MultiMC.Plugins.StdInstance") - -public: - virtual QList getInstanceTypes(); -}; - -#endif // STDINSTPLUGIN_H +#endif // LIBINSTANCE_CONFIG_H diff --git a/data/appsettings.cpp b/libsettings/src/appsettings.cpp similarity index 96% rename from data/appsettings.cpp rename to libsettings/src/appsettings.cpp index 1d9c4312a..8fe9b8ad9 100644 --- a/data/appsettings.cpp +++ b/libsettings/src/appsettings.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "appsettings.h" +#include "include/appsettings.h" AppSettings* settings; diff --git a/libutil/CMakeLists.txt b/libutil/CMakeLists.txt new file mode 100644 index 000000000..b6eadf506 --- /dev/null +++ b/libutil/CMakeLists.txt @@ -0,0 +1,38 @@ +project(libmmcutil) + +# Find Qt +find_package(Qt5Core REQUIRED) + +# Include Qt headers. +include_directories(${Qt5Base_INCLUDE_DIRS}) +include_directories(${Qt5Network_INCLUDE_DIRS}) + +SET(LIBUTIL_HEADERS +include/libutil_config.h + +include/apputils.h + +include/pathutils.h +include/osutils.h + +include/inifile.h + +include/siglist.h +include/siglist_impl.h +) + +SET(LIBUTIL_SOURCES +src/pathutils.cpp +src/osutils.cpp + +src/inifile.cpp +) + +# Set the include dir path. +SET(LIBMMCUTIL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE) + +add_definitions(-DLIBMMCUTIL_LIBRARY) + +add_library(libmmcutil SHARED ${LIBUTIL_SOURCES} ${LIBUTIL_HEADERS}) +qt5_use_modules(libmmcutil Core) +target_link_libraries(libmmcutil) diff --git a/util/apputils.h b/libutil/include/apputils.h similarity index 100% rename from util/apputils.h rename to libutil/include/apputils.h diff --git a/data/inifile.h b/libutil/include/inifile.h similarity index 91% rename from data/inifile.h rename to libutil/include/inifile.h index 757838598..1280c7e3d 100644 --- a/data/inifile.h +++ b/libutil/include/inifile.h @@ -20,8 +20,10 @@ #include #include +#include "libutil_config.h" + // Sectionless INI parser (for instance config files) -class INIFile : public QMap +class LIBMMCUTIL_EXPORT INIFile : public QMap { public: explicit INIFile(); diff --git a/plugins/stdinstance/stdinstplugin.cpp b/libutil/include/libutil_config.h similarity index 72% rename from plugins/stdinstance/stdinstplugin.cpp rename to libutil/include/libutil_config.h index 98e12ae0f..41766184b 100644 --- a/plugins/stdinstance/stdinstplugin.cpp +++ b/libutil/include/libutil_config.h @@ -13,15 +13,15 @@ * limitations under the License. */ -#include "stdinstplugin.h" +#ifndef LIBUTIL_CONFIG_H +#define LIBUTIL_CONFIG_H -#include +#include -#include "stdinstancetype.h" +#ifdef LIBMMCUTIL_LIBRARY +# define LIBMMCUTIL_EXPORT Q_DECL_EXPORT +#else +# define LIBMMCUTIL_EXPORT Q_DECL_IMPORT +#endif -QList StdInstPlugin::getInstanceTypes() -{ - QList types; - types.push_back(new StdInstanceType(this)); - return types; -} +#endif // LIBUTIL_CONFIG_H diff --git a/util/osutils.h b/libutil/include/osutils.h similarity index 89% rename from util/osutils.h rename to libutil/include/osutils.h index f779ea2df..c5d4bb613 100644 --- a/util/osutils.h +++ b/libutil/include/osutils.h @@ -26,7 +26,4 @@ #define LINUX 1 #endif -// Opens the given file in the default application. -void openInDefaultProgram(QString filename); - #endif // OSUTILS_H diff --git a/util/pathutils.h b/libutil/include/pathutils.h similarity index 74% rename from util/pathutils.h rename to libutil/include/pathutils.h index 1922e3a08..d5f106efb 100644 --- a/util/pathutils.h +++ b/libutil/include/pathutils.h @@ -18,9 +18,11 @@ #include -QString PathCombine(QString path1, QString path2); -QString PathCombine(QString path1, QString path2, QString path3); +#include "libutil_config.h" -QString AbsolutePath(QString path); +LIBMMCUTIL_EXPORT QString PathCombine(QString path1, QString path2); +LIBMMCUTIL_EXPORT QString PathCombine(QString path1, QString path2, QString path3); + +LIBMMCUTIL_EXPORT QString AbsolutePath(QString path); #endif // PATHUTILS_H diff --git a/data/siglist.h b/libutil/include/siglist.h similarity index 100% rename from data/siglist.h rename to libutil/include/siglist.h diff --git a/data/siglist_impl.h b/libutil/include/siglist_impl.h similarity index 100% rename from data/siglist_impl.h rename to libutil/include/siglist_impl.h diff --git a/data/inifile.cpp b/libutil/src/inifile.cpp similarity index 98% rename from data/inifile.cpp rename to libutil/src/inifile.cpp index 2d68caf6f..43545a4a8 100644 --- a/data/inifile.cpp +++ b/libutil/src/inifile.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "inifile.h" +#include "include/inifile.h" #include #include diff --git a/util/osutils.cpp b/libutil/src/osutils.cpp similarity index 78% rename from util/osutils.cpp rename to libutil/src/osutils.cpp index 6b0955185..9a85d1e54 100644 --- a/util/osutils.cpp +++ b/libutil/src/osutils.cpp @@ -13,13 +13,7 @@ * limitations under the License. */ -#include "osutils.h" +#include "include/osutils.h" -#include #include #include - -void openInDefaultProgram(QString filename) -{ - QDesktopServices::openUrl("file:///" + QFileInfo(filename).absolutePath()); -} diff --git a/util/pathutils.cpp b/libutil/src/pathutils.cpp similarity index 97% rename from util/pathutils.cpp rename to libutil/src/pathutils.cpp index 8610b80d9..8e91bf316 100644 --- a/util/pathutils.cpp +++ b/libutil/src/pathutils.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "pathutils.h" +#include "include/pathutils.h" #include #include diff --git a/main.cpp b/main.cpp index 29c11e875..b78774a8c 100644 --- a/main.cpp +++ b/main.cpp @@ -17,12 +17,12 @@ #include "gui/mainwindow.h" #include -#include "data/appsettings.h" +#include "appsettings.h" #include "data/loginresponse.h" #include "data/plugin/pluginmanager.h" -#include "util/pathutils.h" +#include "pathutils.h" int main(int argc, char *argv[]) { diff --git a/plugins/stdinstance/CMakeLists.txt b/plugins/stdinstance/CMakeLists.txt index 503bda751..0bb466ec5 100644 --- a/plugins/stdinstance/CMakeLists.txt +++ b/plugins/stdinstance/CMakeLists.txt @@ -10,22 +10,40 @@ find_package(Qt5Network REQUIRED) include_directories(${Qt5Base_INCLUDE_DIRS}) include_directories(${Qt5Network_INCLUDE_DIRS}) -# Include MultiMC's headers. -include_directories(../../) +# Include the Java library. +include_directories(${CMAKE_SOURCE_DIR}/java) + +# Include utils library headers. +include_directories(${CMAKE_SOURCE_DIR}/libutil/include) + +# Include settings library headers. +include_directories(${CMAKE_SOURCE_DIR}/libsettings/include) + +# Include instance library headers. +include_directories(${CMAKE_SOURCE_DIR}libinstance/include) SET(STDINST_HEADERS -stdinstplugin.h stdinstancetype.h stdinstance.h ) SET(STDINST_SOURCES -stdinstplugin.cpp stdinstancetype.cpp stdinstance.cpp ) add_library(stdinstance SHARED ${STDINST_SOURCES} ${STDINST_HEADERS}) + set_target_properties(stdinstance PROPERTIES PREFIX "") +set_target_properties(stdinstance PROPERTIES RUNTIME_OUTPUT_DIRECTORY "..") + qt5_use_modules(stdinstance Core Network) -target_link_libraries(stdinstance quazip patchlib) +target_link_libraries(stdinstance +quazip +patchlib + +# Link the util, settings, and instance libraries. +libmmcutil +libmmcsettings +libmmcinst +) diff --git a/plugins/stdinstance/stdinstance.cpp b/plugins/stdinstance/stdinstance.cpp index 194909651..12d86bbcc 100644 --- a/plugins/stdinstance/stdinstance.cpp +++ b/plugins/stdinstance/stdinstance.cpp @@ -17,7 +17,7 @@ #include -#include +#include StdInstance::StdInstance(const QString &rootDir, QObject *parent) : Instance(rootDir, parent) @@ -47,7 +47,8 @@ void StdInstance::updateCurrentVersion(bool keepCurrent) setLastVersionUpdate(time); if (!keepCurrent) { - QString newVersion = javautils::GetMinecraftJarVersion(jar.absoluteFilePath()); + // TODO: Implement GetMinecraftJarVersion function. + QString newVersion = "Unknown";//javautils::GetMinecraftJarVersion(jar.absoluteFilePath()); setCurrentVersion(newVersion); } } diff --git a/plugins/stdinstance/stdinstance.h b/plugins/stdinstance/stdinstance.h index 17c03f15b..d812a9b07 100644 --- a/plugins/stdinstance/stdinstance.h +++ b/plugins/stdinstance/stdinstance.h @@ -16,7 +16,7 @@ #ifndef STDINSTANCE_H #define STDINSTANCE_H -#include +#include class StdInstance : public Instance { diff --git a/plugins/stdinstance/stdinstance.json b/plugins/stdinstance/stdinstance.json index 0967ef424..704f0b733 100644 --- a/plugins/stdinstance/stdinstance.json +++ b/plugins/stdinstance/stdinstance.json @@ -1 +1,8 @@ -{} +{ + "api": "MultiMC5-API-1", + + "name": "Standard Instance Plugin", + "summary": "A plugin that provides standard Minecraft instances.", + "description": "This is a built-in plugin that provides the standard Minecraft instance.", + "version": "0.1" +} diff --git a/plugins/stdinstance/stdinstancetype.cpp b/plugins/stdinstance/stdinstancetype.cpp index 3e9e00a0f..9b7aa9945 100644 --- a/plugins/stdinstance/stdinstancetype.cpp +++ b/plugins/stdinstance/stdinstancetype.cpp @@ -16,7 +16,7 @@ #include "stdinstancetype.h" StdInstanceType::StdInstanceType(QObject *parent) : - InstanceType(parent) + QObject(parent) { } diff --git a/plugins/stdinstance/stdinstancetype.h b/plugins/stdinstance/stdinstancetype.h index 9516aa801..4f659ba74 100644 --- a/plugins/stdinstance/stdinstancetype.h +++ b/plugins/stdinstance/stdinstancetype.h @@ -16,11 +16,15 @@ #ifndef STDINSTANCETYPE_H #define STDINSTANCETYPE_H -#include +#include -class StdInstanceType : public InstanceType +#define StdInstanceType_IID "net.forkk.MultiMC.StdInstanceType/0.1" + +class StdInstanceType : public QObject, InstanceTypeInterface { Q_OBJECT + Q_PLUGIN_METADATA(IID StdInstanceType_IID FILE "stdinstance.json") + Q_INTERFACES(InstanceTypeInterface) public: explicit StdInstanceType(QObject *parent = 0); From f3b6eeeac4e1606a288c7f12fec271fbb7f120f6 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 20 Feb 2013 19:45:00 -0600 Subject: [PATCH 09/15] Got instance loading working. --- libinstance/include/instanceloader.h | 11 +++++--- libinstance/include/instancetypeinterface.h | 4 +-- libinstance/src/instancelist.cpp | 9 ++++--- libinstance/src/instanceloader.cpp | 6 ++--- plugins/stdinstance/stdinstancetype.cpp | 28 +++++++++++++++++++-- plugins/stdinstance/stdinstancetype.h | 4 +-- 6 files changed, 46 insertions(+), 16 deletions(-) diff --git a/libinstance/include/instanceloader.h b/libinstance/include/instanceloader.h index 396966392..96be36fb3 100644 --- a/libinstance/include/instanceloader.h +++ b/libinstance/include/instanceloader.h @@ -51,6 +51,7 @@ public: * - InstExists is returned by createInstance() if the given instance directory is already an instance. * - NotAnInstance is returned by loadInstance() if the given instance directory is not a valid instance. * - WrongInstType is returned by loadInstance() if the given instance directory's type doesn't match the given type. + * - CantCreateDir is returned by createInstance( if the given instance directory can't be created.) */ enum InstTypeError { @@ -62,7 +63,8 @@ public: TypeNotRegistered, InstExists, NotAnInstance, - WrongInstType + WrongInstType, + CantCreateDir }; /*! @@ -83,8 +85,9 @@ public: * \return An InstTypeError error code. * - TypeNotRegistered if the given type is not registered with the InstanceLoader. * - InstExists if the given instance directory is already an instance. + * - CantCreateDir if the given instance directory cannot be created. */ - InstTypeError createInstance(Instance *inst, const InstanceTypeInterface *type, const QString &instDir); + InstTypeError createInstance(Instance *&inst, const InstanceTypeInterface *type, const QString &instDir); /*! * \brief Loads an instance from the given directory. @@ -97,7 +100,7 @@ public: * - NotAnInstance if the given instance directory isn't a valid instance. * - WrongInstType if the given instance directory's type isn't the same as the given type. */ - InstTypeError loadInstance(Instance *inst, const InstanceTypeInterface *type, const QString &instDir); + InstTypeError loadInstance(Instance *&inst, const InstanceTypeInterface *type, const QString &instDir); /*! * \brief Loads an instance from the given directory. @@ -108,7 +111,7 @@ public: * - TypeNotRegistered if the instance's type is not registered with the InstanceLoader. * - NotAnInstance if the given instance directory isn't a valid instance. */ - InstTypeError loadInstance(Instance *inst, const QString &instDir); + InstTypeError loadInstance(Instance *&inst, const QString &instDir); /*! * \brief Finds an instance type with the given ID. diff --git a/libinstance/include/instancetypeinterface.h b/libinstance/include/instancetypeinterface.h index a061b9d2e..30a12d99d 100644 --- a/libinstance/include/instancetypeinterface.h +++ b/libinstance/include/instancetypeinterface.h @@ -67,7 +67,7 @@ protected: * TypeNotRegistered if the given type is not registered with the InstanceLoader. * InstExists if the given instance directory is already an instance. */ - virtual InstanceLoader::InstTypeError createInstance(Instance *inst, const QString &instDir) const = 0; + virtual InstanceLoader::InstTypeError createInstance(Instance *&inst, const QString &instDir) const = 0; /*! * \brief Loads an instance from the given directory. @@ -78,7 +78,7 @@ protected: * NotAnInstance if the given instance directory isn't a valid instance. * WrongInstType if the given instance directory's type isn't an instance of this type. */ - virtual InstanceLoader::InstTypeError loadInstance(Instance *inst, const QString &instDir) const = 0; + virtual InstanceLoader::InstTypeError loadInstance(Instance *&inst, const QString &instDir) const = 0; }; Q_DECLARE_INTERFACE(InstanceTypeInterface, InstanceTypeInterface_IID) diff --git a/libinstance/src/instancelist.cpp b/libinstance/src/instancelist.cpp index 15f79d05d..3b0b668f3 100644 --- a/libinstance/src/instancelist.cpp +++ b/libinstance/src/instancelist.cpp @@ -43,9 +43,10 @@ InstanceList::InstListError InstanceList::loadList() QString subDir = iter.next(); if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) { - QSharedPointer inst; + Instance *instPtr = NULL; + InstanceLoader::InstTypeError error = InstanceLoader::get(). - loadInstance(inst.data(), subDir); + loadInstance(instPtr, subDir); if (error != InstanceLoader::NoError && error != InstanceLoader::NotAnInstance) @@ -66,13 +67,15 @@ InstanceList::InstListError InstanceList::loadList() } qDebug(errorMsg.toUtf8()); } - else if (!inst.data()) + else if (!instPtr) { qDebug(QString("Error loading instance %1. Instance loader returned null."). arg(QFileInfo(subDir).baseName()).toUtf8()); } else { + QSharedPointer inst(instPtr); + qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8()); inst->setParent(this); append(QSharedPointer(inst)); diff --git a/libinstance/src/instanceloader.cpp b/libinstance/src/instanceloader.cpp index eff9d56ee..620562b6f 100644 --- a/libinstance/src/instanceloader.cpp +++ b/libinstance/src/instanceloader.cpp @@ -49,7 +49,7 @@ InstanceLoader::InstTypeError InstanceLoader::registerInstanceType(InstanceTypeI return NoError; } -InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *inst, +InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *&inst, const InstanceTypeInterface *type, const QString &instDir) { @@ -61,7 +61,7 @@ InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *inst, return type->createInstance(inst, instDir); } -InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, +InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *&inst, const InstanceTypeInterface *type, const QString &instDir) { @@ -72,7 +72,7 @@ InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, return type->loadInstance(inst, instDir); } -InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, +InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *&inst, const QString &instDir) { QFileInfo instConfig(PathCombine(instDir, "instance.cfg")); diff --git a/plugins/stdinstance/stdinstancetype.cpp b/plugins/stdinstance/stdinstancetype.cpp index 9b7aa9945..5a3a6649b 100644 --- a/plugins/stdinstance/stdinstancetype.cpp +++ b/plugins/stdinstance/stdinstancetype.cpp @@ -15,20 +15,44 @@ #include "stdinstancetype.h" +#include +#include + +#include "stdinstance.h" + StdInstanceType::StdInstanceType(QObject *parent) : QObject(parent) { } -InstanceLoader::InstTypeError StdInstanceType::createInstance(Instance *inst, +InstanceLoader::InstTypeError StdInstanceType::createInstance(Instance *&inst, const QString &instDir) const { + QFileInfo rootDir(instDir); + + if (!rootDir.exists() && !QDir().mkdir(rootDir.path())) + { + return InstanceLoader::CantCreateDir; + } + + StdInstance *stdInst = new StdInstance(instDir); + + // TODO: Verify that the instance is valid. + + inst = stdInst; + return InstanceLoader::NoError; } -InstanceLoader::InstTypeError StdInstanceType::loadInstance(Instance *inst, +InstanceLoader::InstTypeError StdInstanceType::loadInstance(Instance *&inst, const QString &instDir) const { + StdInstance *stdInst = new StdInstance(instDir); + + // TODO: Verify that the instance is valid. + + inst = stdInst; + return InstanceLoader::NoError; } diff --git a/plugins/stdinstance/stdinstancetype.h b/plugins/stdinstance/stdinstancetype.h index 4f659ba74..b8382a971 100644 --- a/plugins/stdinstance/stdinstancetype.h +++ b/plugins/stdinstance/stdinstancetype.h @@ -34,9 +34,9 @@ public: virtual QString description() const { return "A standard Minecraft instance."; } - virtual InstanceLoader::InstTypeError createInstance(Instance *inst, const QString &instDir) const; + virtual InstanceLoader::InstTypeError createInstance(Instance *&inst, const QString &instDir) const; - virtual InstanceLoader::InstTypeError loadInstance(Instance *inst, const QString &instDir) const; + virtual InstanceLoader::InstTypeError loadInstance(Instance *&inst, const QString &instDir) const; }; #endif // STDINSTANCETYPE_H From faddeb2c130157496cd2fd2853fd33a4fc95a0d1 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 21 Feb 2013 10:32:13 -0600 Subject: [PATCH 10/15] Reorganized the main CMakeLists file and added an icon on Windows. --- CMakeLists.txt | 197 +++++++++++++++++++++--------------- multimc.rc | 1 + resources/icons/MultiMC.ico | Bin 0 -> 76126 bytes 3 files changed, 117 insertions(+), 81 deletions(-) create mode 100644 multimc.rc create mode 100644 resources/icons/MultiMC.ico diff --git a/CMakeLists.txt b/CMakeLists.txt index eea4ded54..e6a1d0cca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,31 +1,34 @@ cmake_minimum_required(VERSION 2.8.9) project(MultiMC) -set(CMAKE_AUTOMOC ON) -set(CMAKE_INCLUDE_CURRENT_DIR ON) +######## Set CMake options ######## +SET(CMAKE_AUTOMOC ON) +SET(CMAKE_INCLUDE_CURRENT_DIR ON) +# Output all executables and shared libs in the main build folder, not in subfolders. SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) -#### Check for machine endianness #### -INCLUDE(TestBigEndian) -TEST_BIG_ENDIAN(BIGENDIAN) -IF(${BIGENDIAN}) - ADD_DEFINITIONS(-DMULTIMC_BIG_ENDIAN) -ENDIF(${BIGENDIAN}) + +################################ INCLUDE LIBRARIES ################################ # First, include header overrides include_directories(hacks) -#### Find the required Qt parts #### + +######## 3rd Party Libs ######## + +# Find the required Qt parts find_package(Qt5Widgets REQUIRED) find_package(Qt5Network REQUIRED) -#find_package(Qt5Declarative) include_directories(${Qt5Widgets_INCLUDE_DIRS}) -# find ZLIB for quazip +# Find ZLIB for quazip find_package(ZLIB REQUIRED) + +######## Included Libs ######## + # Add quazip add_subdirectory(quazip) @@ -37,6 +40,8 @@ include_directories(patchlib) add_subdirectory(launcher) +######## MultiMC Libs ######## + # Add the util library. add_subdirectory(libutil) include_directories(${LIBMMCUTIL_INCLUDE_DIR}) @@ -53,64 +58,84 @@ include_directories(${LIBMMCINST_INCLUDE_DIR}) add_subdirectory(plugins/stdinstance) + +################################ SET UP BUILD OPTIONS ################################ + +######## Check endianness ######## +INCLUDE(TestBigEndian) +TEST_BIG_ENDIAN(BIGENDIAN) +IF(${BIGENDIAN}) + ADD_DEFINITIONS(-DMULTIMC_BIG_ENDIAN) +ENDIF(${BIGENDIAN}) + + +######## Set module path ######## +SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}") + + +######## Set compiler flags ######## IF(APPLE) - # assume clang 4.1.0+, add C++0x/C++11 stuff - message(STATUS "Using APPLE CMAKE_CXX_FLAGS") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++") + # assume clang 4.1.0+, add C++0x/C++11 stuff + message(STATUS "Using APPLE CMAKE_CXX_FLAGS") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++") ELSEIF(UNIX) - # assume GCC, add C++0x/C++11 stuff - message(STATUS "Using UNIX CMAKE_CXX_FLAGS") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + # assume GCC, add C++0x/C++11 stuff + MESSAGE(STATUS "Using UNIX CMAKE_CXX_FLAGS") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") ELSEIF(MINGW) - message(STATUS "Using MINGW CMAKE_CXX_FLAGS") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") + MESSAGE(STATUS "Using MINGW CMAKE_CXX_FLAGS") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") ENDIF() -# Set the path where CMake will look for modules. -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}") +######## Set version numbers ######## +SET(MultiMC_VERSION_MAJOR 5) +SET(MultiMC_VERSION_MINOR 0) +SET(MultiMC_VERSION_REV 0) -set(MultiMC_VERSION_MAJOR 5) -set(MultiMC_VERSION_MINOR 0) -set(MultiMC_VERSION_REV 0) - +# Jenkins build number. SET(MultiMC_VERSION_BUILD 0 CACHE STRING "Build number.") -message(STATUS "MultiMC build #${MultiMC_VERSION_BUILD}") +MESSAGE(STATUS "MultiMC build #${MultiMC_VERSION_BUILD}") -IF (DEFINED MultiMC_BUILD_TAG) - message(STATUS "Build tag: ${MultiMC_BUILD_TAG}") -ELSE () - message(STATUS "No build tag specified.") -ENDIF () -if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - set (MultiMC_ARCH "x64" - CACHE STRING "Architecture we're building for.") -else() - set (MultiMC_ARCH "x86" - CACHE STRING "Architecture we're building for.") -endif() -message (STATUS "Architecture is ${MultiMC_ARCH}") - -SET(MultiMC_Extra_Label "") - -IF (WIN32) - SET(MultiMC_JOB_NAME "MultiMC4Windows" CACHE STRING "Jenkins job name.") -ELSEIF(UNIX AND APPLE) - SET(MultiMC_JOB_NAME "MultiMC4OSX" CACHE STRING "Jenkins job name.") - # This is here because the scheme doesn't exactly apply to every kind of build... - SET(MultiMC_Extra_Label ",label=osx") +######## Set Jenkins info ######## +# Jenkins build tag +IF(DEFINED MultiMC_BUILD_TAG) + MESSAGE(STATUS "Build tag: ${MultiMC_BUILD_TAG}") ELSE() - SET(MultiMC_JOB_NAME "MultiMC4Linux" CACHE STRING "Jenkins job name.") + MESSAGE(STATUS "No build tag specified.") ENDIF() +# Architecture detection +IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(MultiMC_ARCH "x64" CACHE STRING "Architecture we're building for.") +ELSE() + SET(MultiMC_ARCH "x86" CACHE STRING "Architecture we're building for.") +ENDIF() +MESSAGE(STATUS "Architecture is ${MultiMC_ARCH}") + +# Jenkins job name +IF(WIN32) + SET(MultiMC_JOB_NAME "MultiMC5Windows" CACHE STRING "Jenkins job name.") +ELSEIF(UNIX AND APPLE) + SET(MultiMC_JOB_NAME "MultiMC5OSX" CACHE STRING "Jenkins job name.") +ELSE() + SET(MultiMC_JOB_NAME "MultiMC5Linux" CACHE STRING "Jenkins job name.") +ENDIF() + +# Jenkins URL SET(MultiMC_JOB_URL "http://ci.forkk.net/job/${MultiMC_JOB_NAME}/arch=${MultiMC_ARCH}${MultiMC_Extra_Label}/" CACHE STRING "URL of the jenkins job to pull updates from.") -message(STATUS "Job URL: ${MultiMC_JOB_URL}") +MESSAGE(STATUS "Job URL: ${MultiMC_JOB_URL}") +######## Configure header ######## configure_file("${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_BINARY_DIR}/config.h") + +################################ FILES ################################ + +######## Headers ######## SET(MULTIMC_HEADERS gui/mainwindow.h gui/modeditwindow.h @@ -139,6 +164,8 @@ tasks/task.h tasks/logintask.h ) + +######## Sources ######## SET(MULTIMC_SOURCES main.cpp @@ -162,7 +189,9 @@ tasks/task.cpp tasks/logintask.cpp ) -SET(MULTIMC5_UIS + +######## UIs ######## +SET(MULTIMC_UIS gui/mainwindow.ui gui/modeditwindow.ui gui/settingsdialog.ui @@ -171,39 +200,51 @@ gui/logindialog.ui gui/taskdialog.ui ) -################################ Install ################################ -################ ICNS File ################ +######## Windows resource files ######## +IF(WIN32) +SET(MULTIMC_RCS multimc.rc) +ENDIF() + +################################ COMPILE ################################ + +# ICNS file for OS X IF(APPLE) SET(MACOSX_BUNDLE_ICON_FILE MultiMC.icns) SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/MultiMC.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) SET(MULTIMC_SOURCES ${MULTIMC_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/MultiMC.icns) ENDIF(APPLE) - -################ Build ################ - -IF (WIN32) +# Link additional libraries +IF(WIN32) SET(MultiMC_LINK_ADDITIONAL_LIBS ${MultiMC_LINK_ADDITIONAL_LIBS} - Qt5::WinMain + Qt5::WinMain # Link WinMain ) -ENDIF (WIN32) +ENDIF(WIN32) +# Tell CMake that MultiMCLauncher.jar is generated. SET_SOURCE_FILES_PROPERTIES(resources/MultiMCLauncher.jar GENERATED) -QT5_WRAP_UI(MULTIMC_UI ${MULTIMC5_UIS}) +# Qt 5 stuff +QT5_WRAP_UI(MULTIMC_UI ${MULTIMC_UIS}) QT5_ADD_RESOURCES(MULTIMC_QRC multimc.qrc) -add_executable(MultiMC MACOSX_BUNDLE WIN32 ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC}) -qt5_use_modules(MultiMC Widgets Network) -target_link_libraries(MultiMC quazip patchlib -libmmcutil libmmcsettings libmmcinst +# Add executable +ADD_EXECUTABLE(MultiMC MACOSX_BUNDLE WIN32 + ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC} ${MULTIMC_RCS}) + +# Link +QT5_USE_MODULES(MultiMC Widgets Network) +TARGET_LINK_LIBRARIES(MultiMC quazip patchlib +libmmcutil libmmcsettings libmmcinst ${MultiMC_LINK_ADDITIONAL_LIBS}) -add_dependencies(MultiMC MultiMCLauncher libmmcutil libmmcsettings libmmcinst) +ADD_DEPENDENCIES(MultiMC MultiMCLauncher libmmcutil libmmcsettings libmmcinst) -################ Dirs ################ +################################ INSTALLATION AND PACKAGING ################################ + +######## Plugin and library folders ######## SET(PLUGIN_DEST_DIR bin) SET(QTCONF_DEST_DIR bin) @@ -214,6 +255,7 @@ IF(WIN32) SET(QTCONF_DEST_DIR .) SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.exe") ENDIF() + IF(APPLE) SET(PLUGIN_DEST_DIR MultiMC.app/Contents/MacOS) SET(QTCONF_DEST_DIR MultiMC.app/Contents/Resources) @@ -224,19 +266,20 @@ SET(QT_PLUGINS_DIR ${Qt5_DIR}/plugins) SET(QT_LIBRARY_DIRS ${Qt5_DIR}/lib) -################ OS X Bundle Info ################ +######## OS X Bundle Info ######## IF(APPLE) SET(MACOSX_BUNDLE_BUNDLE_NAME "MultiMC") SET(MACOSX_BUNDLE_INFO_STRING "MultiMC Minecraft launcher and management utility.") - SET(MACOSX_BUNDLE_BUNDLE_VERSION "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_REV}.${MultiMC_VERSION_BUILD}") + SET(MACOSX_BUNDLE_BUNDLE_VERSION + "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_REV}.${MultiMC_VERSION_BUILD}") #SET(MACOSX_BUNDLE_GUI_IDENTIFIER "") SET(MACOSX_BUNDLE_ICON_FILE MultiMC.icns) ENDIF(APPLE) -################ Install ################ +######## Install ######## -# Executable +#### Executable #### IF(WIN32) INSTALL(TARGETS MultiMC BUNDLE DESTINATION . COMPONENT Runtime @@ -257,7 +300,8 @@ INSTALL(TARGETS MultiMC ENDIF() ENDIF() -# Plugins + +#### Plugins #### # Image formats INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime) @@ -286,16 +330,7 @@ INSTALL(CODE " " COMPONENT Runtime) -#GET_TARGET_PROPERTY(BINARY_LOCATION MultiMC LOCATION) -#CONFIGURE_FILE( -# "${CMAKE_CURRENT_SOURCE_DIR}/dependencies.cmake.in" -# "${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake" -# @ONLY -# ) -#INSTALL(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake") - - -################ Package ################ +######## Package ######## # Package with CPack IF(UNIX) diff --git a/multimc.rc b/multimc.rc new file mode 100644 index 000000000..decf7d3ab --- /dev/null +++ b/multimc.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "resources/icons/MultiMC.ico" diff --git a/resources/icons/MultiMC.ico b/resources/icons/MultiMC.ico new file mode 100644 index 0000000000000000000000000000000000000000..734af0fb1004cc7afc5115cc1d689980d009ec44 GIT binary patch literal 76126 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 GIs^b=zPu#> literal 0 HcmV?d00001 From 96e4f73a94e0697ce7200e09983d447220ea5a0b Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 21 Feb 2013 11:02:48 -0600 Subject: [PATCH 11/15] Include Git commit hash in config.h --- CMakeLists.txt | 19 ++++++++++++++++++- config.h.in | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e6a1d0cca..edb58ef27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,10 +93,27 @@ SET(MultiMC_VERSION_MAJOR 5) SET(MultiMC_VERSION_MINOR 0) SET(MultiMC_VERSION_REV 0) -# Jenkins build number. +# Jenkins build number SET(MultiMC_VERSION_BUILD 0 CACHE STRING "Build number.") MESSAGE(STATUS "MultiMC build #${MultiMC_VERSION_BUILD}") +# Check the current Git commit +execute_process(COMMAND git rev-parse HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE GIT_COMMIT_CHECK_RESULTVAR + OUTPUT_VARIABLE GIT_COMMIT_CHECK_OUTVAR + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# If Git executed successfully +IF(GIT_COMMIT_CHECK_RESULTVAR EQUAL 0) + SET(MultiMC_GIT_COMMIT "${GIT_COMMIT_CHECK_OUTVAR}") + MESSAGE(STATUS "Git commit: ${MultiMC_GIT_COMMIT}") +ELSE() + SET(MultiMC_GIT_COMMIT "Unknown") + MESSAGE(STATUS "Failed to check Git commit. ${GIT_COMMIT_CHECK_RESULTVAR}") +ENDIF() + ######## Set Jenkins info ######## # Jenkins build tag diff --git a/config.h.in b/config.h.in index de53ac935..fbc5aed26 100644 --- a/config.h.in +++ b/config.h.in @@ -3,6 +3,8 @@ #define VERSION_REVISION @MultiMC_VERSION_REV@ #define VERSION_BUILD @MultiMC_VERSION_BUILD@ +#define GIT_COMMIT "@MultiMC_GIT_COMMIT@" + #define VERSION_STR "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_REV@.@MultiMC_VERSION_BUILD@" #define x86 1 From e9ef332ec409209626716da43ab8bb14651723b4 Mon Sep 17 00:00:00 2001 From: Andrew Okin Date: Thu, 21 Feb 2013 12:10:10 -0600 Subject: [PATCH 12/15] Fixed some issues with GCC. --- libinstance/include/instancelist.h | 2 +- libinstance/src/instanceloader.cpp | 2 +- libutil/include/siglist.h | 2 ++ libutil/include/siglist_impl.h | 20 ++++++++++---------- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libinstance/include/instancelist.h b/libinstance/include/instancelist.h index f6be815c9..d5b8c196f 100644 --- a/libinstance/include/instancelist.h +++ b/libinstance/include/instancelist.h @@ -26,7 +26,7 @@ class Instance; -class LIBMMCINST_EXPORT InstanceList : public QObject, public SigList> +class LIBMMCINST_EXPORT InstanceList : public QObject, public SigList< QSharedPointer > { Q_OBJECT public: diff --git a/libinstance/src/instanceloader.cpp b/libinstance/src/instanceloader.cpp index 620562b6f..9d98230f9 100644 --- a/libinstance/src/instanceloader.cpp +++ b/libinstance/src/instanceloader.cpp @@ -100,7 +100,7 @@ InstTypeList InstanceLoader::typeList() { InstTypeList typeList; - for (auto iter = m_typeMap.begin(); iter != m_typeMap.end(); iter++) + for (QMap::iterator iter = m_typeMap.begin(); iter != m_typeMap.end(); iter++) { typeList.append(*iter); } diff --git a/libutil/include/siglist.h b/libutil/include/siglist.h index b6432b6e2..347cf7522 100644 --- a/libutil/include/siglist.h +++ b/libutil/include/siglist.h @@ -26,6 +26,8 @@ template class SigList : public QList { +private: + typedef typename QList::iterator iterator; public: explicit SigList() : QList() {} diff --git a/libutil/include/siglist_impl.h b/libutil/include/siglist_impl.h index 16ddd9b03..cb37ea4b0 100644 --- a/libutil/include/siglist_impl.h +++ b/libutil/include/siglist_impl.h @@ -19,7 +19,7 @@ template void SigList::append(const T &value) { QList::append(value); - onItemAdded(value, length() - 1); + onItemAdded(value, QList::length() - 1); } template @@ -32,7 +32,7 @@ void SigList::prepend(const T &value) template void SigList::append(const QList &other) { - int index = length(); + int index = QList::length(); QList::append(other); onItemsAdded(other, index); } @@ -45,7 +45,7 @@ void SigList::clear() } template -void SigList::erase(QList::iterator pos) +void SigList::erase(SigList::iterator pos) { T value = *pos; int index = indexOf(*pos); @@ -54,12 +54,12 @@ void SigList::erase(QList::iterator pos) } template -void SigList::erase(QList::iterator first, QList::iterator last) +void SigList::erase(SigList::iterator first, SigList::iterator last) { QList removedValues; int firstIndex = indexOf(*first); - for (QList::iterator iter = first; iter < last; iter++) + for (SigList::iterator iter = first; iter < last; iter++) { removedValues << *iter; QList::erase(iter); @@ -76,7 +76,7 @@ void SigList::insert(int i, const T &t) } template -void SigList::insert(QList::iterator before, const T &t) +void SigList::insert(SigList::iterator before, const T &t) { QList::insert(before, t); onItemAdded(t, indexOf(t)); @@ -85,7 +85,7 @@ void SigList::insert(QList::iterator before, const T &t) template void SigList::move(int from, int to) { - const T &item = at(from); + const T &item = QList::at(from); QList::move(from, to); onItemMoved(item, from, to); } @@ -120,8 +120,8 @@ void SigList::swap(QList &other) template void SigList::swap(int i, int j) { - const T &item1 = at(i); - const T &item2 = at(j); + const T &item1 = QList::at(i); + const T &item2 = QList::at(j); QList::swap(i, j); onItemMoved(item1, i, j); onItemMoved(item2, j, i); @@ -144,7 +144,7 @@ T SigList::takeFirst() template T SigList::takeLast() { - return takeAt(length() - 1); + return takeAt(QList::length() - 1); } template From 36499049741c15f7f26bc157128976d1d9a75319 Mon Sep 17 00:00:00 2001 From: Andrew Okin Date: Thu, 21 Feb 2013 12:35:33 -0600 Subject: [PATCH 13/15] Fixed CXX flags. --- CMakeLists.txt | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index edb58ef27..0cb80bbcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,19 @@ SET(CMAKE_INCLUDE_CURRENT_DIR ON) # Output all executables and shared libs in the main build folder, not in subfolders. SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) +######## Set compiler flags ######## +IF(APPLE) + # assume clang 4.1.0+, add C++0x/C++11 stuff + message(STATUS "Using APPLE CMAKE_CXX_FLAGS") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++") +ELSEIF(UNIX) + # assume GCC, add C++0x/C++11 stuff + MESSAGE(STATUS "Using UNIX CMAKE_CXX_FLAGS") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +ELSEIF(MINGW) + MESSAGE(STATUS "Using MINGW CMAKE_CXX_FLAGS") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") +ENDIF() ################################ INCLUDE LIBRARIES ################################ @@ -73,21 +86,6 @@ ENDIF(${BIGENDIAN}) SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}") -######## Set compiler flags ######## -IF(APPLE) - # assume clang 4.1.0+, add C++0x/C++11 stuff - message(STATUS "Using APPLE CMAKE_CXX_FLAGS") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++") -ELSEIF(UNIX) - # assume GCC, add C++0x/C++11 stuff - MESSAGE(STATUS "Using UNIX CMAKE_CXX_FLAGS") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") -ELSEIF(MINGW) - MESSAGE(STATUS "Using MINGW CMAKE_CXX_FLAGS") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") -ENDIF() - - ######## Set version numbers ######## SET(MultiMC_VERSION_MAJOR 5) SET(MultiMC_VERSION_MINOR 0) From 2020d9c24bf0c2d024a3f42f38d7e106ab8a49eb Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 21 Feb 2013 12:42:16 -0600 Subject: [PATCH 14/15] Fixed MSVC issues. --- libutil/include/siglist.h | 9 +++------ libutil/include/siglist_impl.h | 6 +++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/libutil/include/siglist.h b/libutil/include/siglist.h index 347cf7522..dcae7c041 100644 --- a/libutil/include/siglist.h +++ b/libutil/include/siglist.h @@ -26,9 +26,6 @@ template class SigList : public QList { -private: - typedef typename QList::iterator iterator; - public: explicit SigList() : QList() {} @@ -37,11 +34,11 @@ public: virtual void clear(); - virtual void erase(iterator pos); - virtual void erase(iterator first, iterator last); + virtual void erase(typename QList::iterator pos); + virtual void erase(typename QList::iterator first, typename QList::iterator last); virtual void insert(int i, const T &t); - virtual void insert(iterator before, const T &t); + virtual void insert(typename QList::iterator before, const T &t); virtual void move(int from, int to); diff --git a/libutil/include/siglist_impl.h b/libutil/include/siglist_impl.h index cb37ea4b0..9736b2cf1 100644 --- a/libutil/include/siglist_impl.h +++ b/libutil/include/siglist_impl.h @@ -45,7 +45,7 @@ void SigList::clear() } template -void SigList::erase(SigList::iterator pos) +void SigList::erase(typename QList::iterator pos) { T value = *pos; int index = indexOf(*pos); @@ -54,7 +54,7 @@ void SigList::erase(SigList::iterator pos) } template -void SigList::erase(SigList::iterator first, SigList::iterator last) +void SigList::erase(typename QList::iterator first, typename QList::iterator last) { QList removedValues; int firstIndex = indexOf(*first); @@ -76,7 +76,7 @@ void SigList::insert(int i, const T &t) } template -void SigList::insert(SigList::iterator before, const T &t) +void SigList::insert(typename QList::iterator before, const T &t) { QList::insert(before, t); onItemAdded(t, indexOf(t)); From 50d1f62bf4a8d70466100463238228bc8305a5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 21 Feb 2013 19:59:34 +0100 Subject: [PATCH 15/15] More GCC fixes --- java/{endian.h => javaendian.h} | 0 java/membuffer.h | 2 +- libutil/include/siglist_impl.h | 10 +++++----- 3 files changed, 6 insertions(+), 6 deletions(-) rename java/{endian.h => javaendian.h} (100%) diff --git a/java/endian.h b/java/javaendian.h similarity index 100% rename from java/endian.h rename to java/javaendian.h diff --git a/java/membuffer.h b/java/membuffer.h index 48304b9f7..2ea3a69ba 100644 --- a/java/membuffer.h +++ b/java/membuffer.h @@ -3,7 +3,7 @@ #include #include #include -#include "endian.h" +#include "javaendian.h" namespace util { diff --git a/libutil/include/siglist_impl.h b/libutil/include/siglist_impl.h index 9736b2cf1..5cdc632a0 100644 --- a/libutil/include/siglist_impl.h +++ b/libutil/include/siglist_impl.h @@ -48,7 +48,7 @@ template void SigList::erase(typename QList::iterator pos) { T value = *pos; - int index = indexOf(*pos); + int index = QList::indexOf(*pos); QList::erase(pos); onItemRemoved(value, index); } @@ -57,9 +57,9 @@ template void SigList::erase(typename QList::iterator first, typename QList::iterator last) { QList removedValues; - int firstIndex = indexOf(*first); + int firstIndex = QList::indexOf(*first); - for (SigList::iterator iter = first; iter < last; iter++) + for (auto iter = first; iter < last; iter++) { removedValues << *iter; QList::erase(iter); @@ -79,7 +79,7 @@ template void SigList::insert(typename QList::iterator before, const T &t) { QList::insert(before, t); - onItemAdded(t, indexOf(t)); + onItemAdded(t, QList::indexOf(t)); } template @@ -101,7 +101,7 @@ int SigList::removeAll(const T &t) template bool SigList::removeOne(const T &t) { - int index = indexOf(t); + int index = QList::indexOf(t); if (QList::removeOne(t)) { onItemRemoved(t, index);