@ -15,74 +15,55 @@
|
||||
|
||||
#include "BaseEntity.h"
|
||||
|
||||
#include "Json.h"
|
||||
#include "net/ApiDownload.h"
|
||||
#include "net/HttpMetaCache.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "Json.h"
|
||||
|
||||
#include "BuildConfig.h"
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
|
||||
class ParsingValidator : public Net::Validator
|
||||
{
|
||||
public: /* con/des */
|
||||
ParsingValidator(Meta::BaseEntity *entity) : m_entity(entity)
|
||||
{
|
||||
};
|
||||
virtual ~ParsingValidator()
|
||||
{
|
||||
};
|
||||
class ParsingValidator : public Net::Validator {
|
||||
public: /* con/des */
|
||||
ParsingValidator(Meta::BaseEntity* entity) : m_entity(entity){};
|
||||
virtual ~ParsingValidator(){};
|
||||
|
||||
public: /* methods */
|
||||
bool init(QNetworkRequest &) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool write(QByteArray & data) override
|
||||
public: /* methods */
|
||||
bool init(QNetworkRequest&) override { return true; }
|
||||
bool write(QByteArray& data) override
|
||||
{
|
||||
this->m_data.append(data);
|
||||
return true;
|
||||
}
|
||||
bool abort() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool validate(QNetworkReply &) override
|
||||
bool abort() override { return true; }
|
||||
bool validate(QNetworkReply&) override
|
||||
{
|
||||
auto fname = m_entity->localFilename();
|
||||
try
|
||||
{
|
||||
try {
|
||||
auto doc = Json::requireDocument(m_data, fname);
|
||||
auto obj = Json::requireObject(doc, fname);
|
||||
m_entity->parse(obj);
|
||||
return true;
|
||||
}
|
||||
catch (const Exception &e)
|
||||
{
|
||||
} catch (const Exception& e) {
|
||||
qWarning() << "Unable to parse response:" << e.cause();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private: /* data */
|
||||
private: /* data */
|
||||
QByteArray m_data;
|
||||
Meta::BaseEntity *m_entity;
|
||||
Meta::BaseEntity* m_entity;
|
||||
};
|
||||
|
||||
Meta::BaseEntity::~BaseEntity()
|
||||
{
|
||||
}
|
||||
Meta::BaseEntity::~BaseEntity() {}
|
||||
|
||||
QUrl Meta::BaseEntity::url() const
|
||||
{
|
||||
auto s = APPLICATION->settings();
|
||||
QString metaOverride = s->get("MetaURLOverride").toString();
|
||||
if(metaOverride.isEmpty())
|
||||
{
|
||||
if (metaOverride.isEmpty()) {
|
||||
return QUrl(BuildConfig.META_URL).resolved(localFilename());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return QUrl(metaOverride).resolved(localFilename());
|
||||
}
|
||||
}
|
||||
@ -90,20 +71,16 @@ QUrl Meta::BaseEntity::url() const
|
||||
bool Meta::BaseEntity::loadLocalFile()
|
||||
{
|
||||
const QString fname = QDir("meta").absoluteFilePath(localFilename());
|
||||
if (!QFile::exists(fname))
|
||||
{
|
||||
if (!QFile::exists(fname)) {
|
||||
return false;
|
||||
}
|
||||
// TODO: check if the file has the expected checksum
|
||||
try
|
||||
{
|
||||
try {
|
||||
auto doc = Json::requireDocument(fname, fname);
|
||||
auto obj = Json::requireObject(doc, fname);
|
||||
parse(obj);
|
||||
return true;
|
||||
}
|
||||
catch (const Exception &e)
|
||||
{
|
||||
} catch (const Exception& e) {
|
||||
qDebug() << QString("Unable to parse file %1: %2").arg(fname, e.cause());
|
||||
// just make sure it's gone and we never consider it again.
|
||||
QFile::remove(fname);
|
||||
@ -114,16 +91,13 @@ bool Meta::BaseEntity::loadLocalFile()
|
||||
void Meta::BaseEntity::load(Net::Mode loadType)
|
||||
{
|
||||
// load local file if nothing is loaded yet
|
||||
if(!isLoaded())
|
||||
{
|
||||
if(loadLocalFile())
|
||||
{
|
||||
if (!isLoaded()) {
|
||||
if (loadLocalFile()) {
|
||||
m_loadStatus = LoadStatus::Local;
|
||||
}
|
||||
}
|
||||
// if we need remote update, run the update task
|
||||
if(loadType == Net::Mode::Offline || !shouldStartRemoteUpdate())
|
||||
{
|
||||
if (loadType == Net::Mode::Offline || !shouldStartRemoteUpdate()) {
|
||||
return;
|
||||
}
|
||||
m_updateTask.reset(new NetJob(QObject::tr("Download of meta file %1").arg(localFilename()), APPLICATION->network()));
|
||||
@ -138,14 +112,12 @@ void Meta::BaseEntity::load(Net::Mode loadType)
|
||||
dl->addValidator(new ParsingValidator(this));
|
||||
m_updateTask->addNetAction(dl);
|
||||
m_updateStatus = UpdateStatus::InProgress;
|
||||
QObject::connect(m_updateTask.get(), &NetJob::succeeded, [&]()
|
||||
{
|
||||
QObject::connect(m_updateTask.get(), &NetJob::succeeded, [&]() {
|
||||
m_loadStatus = LoadStatus::Remote;
|
||||
m_updateStatus = UpdateStatus::Succeeded;
|
||||
m_updateTask.reset();
|
||||
});
|
||||
QObject::connect(m_updateTask.get(), &NetJob::failed, [&]()
|
||||
{
|
||||
QObject::connect(m_updateTask.get(), &NetJob::failed, [&]() {
|
||||
m_updateStatus = UpdateStatus::Failed;
|
||||
m_updateTask.reset();
|
||||
});
|
||||
@ -165,8 +137,7 @@ bool Meta::BaseEntity::shouldStartRemoteUpdate() const
|
||||
|
||||
Task::Ptr Meta::BaseEntity::getCurrentTask()
|
||||
{
|
||||
if(m_updateStatus == UpdateStatus::InProgress)
|
||||
{
|
||||
if (m_updateStatus == UpdateStatus::InProgress) {
|
||||
return m_updateTask;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -22,30 +22,17 @@
|
||||
#include "net/Mode.h"
|
||||
#include "net/NetJob.h"
|
||||
|
||||
namespace Meta
|
||||
{
|
||||
class BaseEntity
|
||||
{
|
||||
public: /* types */
|
||||
namespace Meta {
|
||||
class BaseEntity {
|
||||
public: /* types */
|
||||
using Ptr = std::shared_ptr<BaseEntity>;
|
||||
enum class LoadStatus
|
||||
{
|
||||
NotLoaded,
|
||||
Local,
|
||||
Remote
|
||||
};
|
||||
enum class UpdateStatus
|
||||
{
|
||||
NotDone,
|
||||
InProgress,
|
||||
Failed,
|
||||
Succeeded
|
||||
};
|
||||
enum class LoadStatus { NotLoaded, Local, Remote };
|
||||
enum class UpdateStatus { NotDone, InProgress, Failed, Succeeded };
|
||||
|
||||
public:
|
||||
public:
|
||||
virtual ~BaseEntity();
|
||||
|
||||
virtual void parse(const QJsonObject &obj) = 0;
|
||||
virtual void parse(const QJsonObject& obj) = 0;
|
||||
|
||||
virtual QString localFilename() const = 0;
|
||||
virtual QUrl url() const;
|
||||
@ -56,12 +43,12 @@ public:
|
||||
void load(Net::Mode loadType);
|
||||
Task::Ptr getCurrentTask();
|
||||
|
||||
protected: /* methods */
|
||||
protected: /* methods */
|
||||
bool loadLocalFile();
|
||||
|
||||
private:
|
||||
private:
|
||||
LoadStatus m_loadStatus = LoadStatus::NotLoaded;
|
||||
UpdateStatus m_updateStatus = UpdateStatus::NotDone;
|
||||
NetJob::Ptr m_updateTask;
|
||||
};
|
||||
}
|
||||
} // namespace Meta
|
||||
|
@ -15,84 +15,75 @@
|
||||
|
||||
#include "Index.h"
|
||||
|
||||
#include "VersionList.h"
|
||||
#include "JsonFormat.h"
|
||||
#include "VersionList.h"
|
||||
|
||||
namespace Meta
|
||||
namespace Meta {
|
||||
Index::Index(QObject* parent) : QAbstractListModel(parent) {}
|
||||
Index::Index(const QVector<VersionList::Ptr>& lists, QObject* parent) : QAbstractListModel(parent), m_lists(lists)
|
||||
{
|
||||
Index::Index(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
Index::Index(const QVector<VersionList::Ptr> &lists, QObject *parent)
|
||||
: QAbstractListModel(parent), m_lists(lists)
|
||||
{
|
||||
for (int i = 0; i < m_lists.size(); ++i)
|
||||
{
|
||||
for (int i = 0; i < m_lists.size(); ++i) {
|
||||
m_uids.insert(m_lists.at(i)->uid(), m_lists.at(i));
|
||||
connectVersionList(i, m_lists.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
QVariant Index::data(const QModelIndex &index, int role) const
|
||||
QVariant Index::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size())
|
||||
{
|
||||
if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
VersionList::Ptr list = m_lists.at(index.row());
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
if (index.column() == 0) {
|
||||
return list->humanReadable();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
case UidRole: return list->uid();
|
||||
case NameRole: return list->name();
|
||||
case ListPtrRole: return QVariant::fromValue(list);
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
if (index.column() == 0) {
|
||||
return list->humanReadable();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
case UidRole:
|
||||
return list->uid();
|
||||
case NameRole:
|
||||
return list->name();
|
||||
case ListPtrRole:
|
||||
return QVariant::fromValue(list);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
int Index::rowCount(const QModelIndex &parent) const
|
||||
int Index::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : m_lists.size();
|
||||
}
|
||||
int Index::columnCount(const QModelIndex &parent) const
|
||||
int Index::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : 1;
|
||||
}
|
||||
QVariant Index::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0)
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) {
|
||||
return tr("Name");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
bool Index::hasUid(const QString &uid) const
|
||||
bool Index::hasUid(const QString& uid) const
|
||||
{
|
||||
return m_uids.contains(uid);
|
||||
}
|
||||
|
||||
VersionList::Ptr Index::get(const QString &uid)
|
||||
VersionList::Ptr Index::get(const QString& uid)
|
||||
{
|
||||
VersionList::Ptr out = m_uids.value(uid, nullptr);
|
||||
if(!out)
|
||||
{
|
||||
if (!out) {
|
||||
out = std::make_shared<VersionList>(uid);
|
||||
m_uids[uid] = out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Version::Ptr Index::get(const QString &uid, const QString &version)
|
||||
Version::Ptr Index::get(const QString& uid, const QString& version)
|
||||
{
|
||||
auto list = get(uid);
|
||||
return list->getVersion(version);
|
||||
@ -103,31 +94,23 @@ void Index::parse(const QJsonObject& obj)
|
||||
parseIndex(obj, this);
|
||||
}
|
||||
|
||||
void Index::merge(const std::shared_ptr<Index> &other)
|
||||
void Index::merge(const std::shared_ptr<Index>& other)
|
||||
{
|
||||
const QVector<VersionList::Ptr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists;
|
||||
// initial load, no need to merge
|
||||
if (m_lists.isEmpty())
|
||||
{
|
||||
if (m_lists.isEmpty()) {
|
||||
beginResetModel();
|
||||
m_lists = lists;
|
||||
for (int i = 0; i < lists.size(); ++i)
|
||||
{
|
||||
for (int i = 0; i < lists.size(); ++i) {
|
||||
m_uids.insert(lists.at(i)->uid(), lists.at(i));
|
||||
connectVersionList(i, lists.at(i));
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const VersionList::Ptr &list : lists)
|
||||
{
|
||||
if (m_uids.contains(list->uid()))
|
||||
{
|
||||
} else {
|
||||
for (const VersionList::Ptr& list : lists) {
|
||||
if (m_uids.contains(list->uid())) {
|
||||
m_uids[list->uid()]->mergeFromIndex(list);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
beginInsertRows(QModelIndex(), m_lists.size(), m_lists.size());
|
||||
connectVersionList(m_lists.size(), list);
|
||||
m_lists.append(list);
|
||||
@ -138,11 +121,9 @@ void Index::merge(const std::shared_ptr<Index> &other)
|
||||
}
|
||||
}
|
||||
|
||||
void Index::connectVersionList(const int row, const VersionList::Ptr &list)
|
||||
void Index::connectVersionList(const int row, const VersionList::Ptr& list)
|
||||
{
|
||||
connect(list.get(), &VersionList::nameChanged, this, [this, row]()
|
||||
{
|
||||
emit dataChanged(index(row), index(row), QVector<int>() << Qt::DisplayRole);
|
||||
});
|
||||
}
|
||||
connect(list.get(), &VersionList::nameChanged, this,
|
||||
[this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << Qt::DisplayRole); });
|
||||
}
|
||||
} // namespace Meta
|
||||
|
@ -23,46 +23,38 @@
|
||||
|
||||
class Task;
|
||||
|
||||
namespace Meta
|
||||
{
|
||||
namespace Meta {
|
||||
|
||||
class Index : public QAbstractListModel, public BaseEntity
|
||||
{
|
||||
class Index : public QAbstractListModel, public BaseEntity {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Index(QObject *parent = nullptr);
|
||||
explicit Index(const QVector<VersionList::Ptr> &lists, QObject *parent = nullptr);
|
||||
public:
|
||||
explicit Index(QObject* parent = nullptr);
|
||||
explicit Index(const QVector<VersionList::Ptr>& lists, QObject* parent = nullptr);
|
||||
|
||||
enum
|
||||
{
|
||||
UidRole = Qt::UserRole,
|
||||
NameRole,
|
||||
ListPtrRole
|
||||
};
|
||||
enum { UidRole = Qt::UserRole, NameRole, ListPtrRole };
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex& index, int role) const override;
|
||||
int rowCount(const QModelIndex& parent) const override;
|
||||
int columnCount(const QModelIndex& parent) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
QString localFilename() const override { return "index.json"; }
|
||||
|
||||
// queries
|
||||
VersionList::Ptr get(const QString &uid);
|
||||
Version::Ptr get(const QString &uid, const QString &version);
|
||||
bool hasUid(const QString &uid) const;
|
||||
VersionList::Ptr get(const QString& uid);
|
||||
Version::Ptr get(const QString& uid, const QString& version);
|
||||
bool hasUid(const QString& uid) const;
|
||||
|
||||
QVector<VersionList::Ptr> lists() const { return m_lists; }
|
||||
|
||||
public: // for usage by parsers only
|
||||
void merge(const std::shared_ptr<Index> &other);
|
||||
void parse(const QJsonObject &obj) override;
|
||||
public: // for usage by parsers only
|
||||
void merge(const std::shared_ptr<Index>& other);
|
||||
void parse(const QJsonObject& obj) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
QVector<VersionList::Ptr> m_lists;
|
||||
QHash<QString, VersionList::Ptr> m_uids;
|
||||
|
||||
void connectVersionList(const int row, const VersionList::Ptr &list);
|
||||
void connectVersionList(const int row, const VersionList::Ptr& list);
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace Meta
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include "JsonFormat.h"
|
||||
|
||||
// FIXME: remove this from here... somehow
|
||||
#include "minecraft/OneSixVersionFormat.h"
|
||||
#include "Json.h"
|
||||
#include "minecraft/OneSixVersionFormat.h"
|
||||
|
||||
#include "Index.h"
|
||||
#include "Version.h"
|
||||
@ -25,8 +25,7 @@
|
||||
|
||||
using namespace Json;
|
||||
|
||||
namespace Meta
|
||||
{
|
||||
namespace Meta {
|
||||
|
||||
MetadataVersion currentFormatVersion()
|
||||
{
|
||||
@ -34,13 +33,12 @@ MetadataVersion currentFormatVersion()
|
||||
}
|
||||
|
||||
// Index
|
||||
static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj)
|
||||
static std::shared_ptr<Index> parseIndexInternal(const QJsonObject& obj)
|
||||
{
|
||||
const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages");
|
||||
QVector<VersionList::Ptr> lists;
|
||||
lists.reserve(objects.size());
|
||||
std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj)
|
||||
{
|
||||
std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject& obj) {
|
||||
VersionList::Ptr list = std::make_shared<VersionList>(requireString(obj, "uid"));
|
||||
list->setName(ensureString(obj, "name", QString()));
|
||||
return list;
|
||||
@ -49,7 +47,7 @@ static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj)
|
||||
}
|
||||
|
||||
// Version
|
||||
static Version::Ptr parseCommonVersion(const QString &uid, const QJsonObject &obj)
|
||||
static Version::Ptr parseCommonVersion(const QString& uid, const QJsonObject& obj)
|
||||
{
|
||||
Version::Ptr version = std::make_shared<Version>(uid, requireString(obj, "version"));
|
||||
version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000);
|
||||
@ -63,26 +61,24 @@ static Version::Ptr parseCommonVersion(const QString &uid, const QJsonObject &ob
|
||||
return version;
|
||||
}
|
||||
|
||||
static Version::Ptr parseVersionInternal(const QJsonObject &obj)
|
||||
static Version::Ptr parseVersionInternal(const QJsonObject& obj)
|
||||
{
|
||||
Version::Ptr version = parseCommonVersion(requireString(obj, "uid"), obj);
|
||||
|
||||
version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
|
||||
QString("%1/%2.json").arg(version->uid(), version->version()),
|
||||
obj.contains("order")));
|
||||
version->setData(OneSixVersionFormat::versionFileFromJson(
|
||||
QJsonDocument(obj), QString("%1/%2.json").arg(version->uid(), version->version()), obj.contains("order")));
|
||||
return version;
|
||||
}
|
||||
|
||||
// Version list / package
|
||||
static VersionList::Ptr parseVersionListInternal(const QJsonObject &obj)
|
||||
static VersionList::Ptr parseVersionListInternal(const QJsonObject& obj)
|
||||
{
|
||||
const QString uid = requireString(obj, "uid");
|
||||
|
||||
const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
|
||||
QVector<Version::Ptr> versions;
|
||||
versions.reserve(versionsRaw.size());
|
||||
std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj)
|
||||
{
|
||||
std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject& vObj) {
|
||||
auto version = parseCommonVersion(uid, vObj);
|
||||
version->setProvidesRecommendations();
|
||||
return version;
|
||||
@ -94,23 +90,18 @@ static VersionList::Ptr parseVersionListInternal(const QJsonObject &obj)
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required)
|
||||
MetadataVersion parseFormatVersion(const QJsonObject& obj, bool required)
|
||||
{
|
||||
if (!obj.contains("formatVersion"))
|
||||
{
|
||||
if(required)
|
||||
{
|
||||
if (!obj.contains("formatVersion")) {
|
||||
if (required) {
|
||||
return MetadataVersion::Invalid;
|
||||
}
|
||||
return MetadataVersion::InitialRelease;
|
||||
}
|
||||
if (!obj.value("formatVersion").isDouble())
|
||||
{
|
||||
if (!obj.value("formatVersion").isDouble()) {
|
||||
return MetadataVersion::Invalid;
|
||||
}
|
||||
switch(obj.value("formatVersion").toInt())
|
||||
{
|
||||
switch (obj.value("formatVersion").toInt()) {
|
||||
case 0:
|
||||
case 1:
|
||||
return MetadataVersion::InitialRelease;
|
||||
@ -121,49 +112,45 @@ MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required)
|
||||
|
||||
void serializeFormatVersion(QJsonObject& obj, Meta::MetadataVersion version)
|
||||
{
|
||||
if(version == MetadataVersion::Invalid)
|
||||
{
|
||||
if (version == MetadataVersion::Invalid) {
|
||||
return;
|
||||
}
|
||||
obj.insert("formatVersion", int(version));
|
||||
}
|
||||
|
||||
void parseIndex(const QJsonObject &obj, Index *ptr)
|
||||
void parseIndex(const QJsonObject& obj, Index* ptr)
|
||||
{
|
||||
const MetadataVersion version = parseFormatVersion(obj);
|
||||
switch (version)
|
||||
{
|
||||
case MetadataVersion::InitialRelease:
|
||||
ptr->merge(parseIndexInternal(obj));
|
||||
break;
|
||||
case MetadataVersion::Invalid:
|
||||
throw ParseException(QObject::tr("Unknown format version!"));
|
||||
switch (version) {
|
||||
case MetadataVersion::InitialRelease:
|
||||
ptr->merge(parseIndexInternal(obj));
|
||||
break;
|
||||
case MetadataVersion::Invalid:
|
||||
throw ParseException(QObject::tr("Unknown format version!"));
|
||||
}
|
||||
}
|
||||
|
||||
void parseVersionList(const QJsonObject &obj, VersionList *ptr)
|
||||
void parseVersionList(const QJsonObject& obj, VersionList* ptr)
|
||||
{
|
||||
const MetadataVersion version = parseFormatVersion(obj);
|
||||
switch (version)
|
||||
{
|
||||
case MetadataVersion::InitialRelease:
|
||||
ptr->merge(parseVersionListInternal(obj));
|
||||
break;
|
||||
case MetadataVersion::Invalid:
|
||||
throw ParseException(QObject::tr("Unknown format version!"));
|
||||
switch (version) {
|
||||
case MetadataVersion::InitialRelease:
|
||||
ptr->merge(parseVersionListInternal(obj));
|
||||
break;
|
||||
case MetadataVersion::Invalid:
|
||||
throw ParseException(QObject::tr("Unknown format version!"));
|
||||
}
|
||||
}
|
||||
|
||||
void parseVersion(const QJsonObject &obj, Version *ptr)
|
||||
void parseVersion(const QJsonObject& obj, Version* ptr)
|
||||
{
|
||||
const MetadataVersion version = parseFormatVersion(obj);
|
||||
switch (version)
|
||||
{
|
||||
case MetadataVersion::InitialRelease:
|
||||
ptr->merge(parseVersionInternal(obj));
|
||||
break;
|
||||
case MetadataVersion::Invalid:
|
||||
throw ParseException(QObject::tr("Unknown format version!"));
|
||||
switch (version) {
|
||||
case MetadataVersion::InitialRelease:
|
||||
ptr->merge(parseVersionInternal(obj));
|
||||
break;
|
||||
case MetadataVersion::Invalid:
|
||||
throw ParseException(QObject::tr("Unknown format version!"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,40 +159,34 @@ void parseVersion(const QJsonObject &obj, Version *ptr)
|
||||
{"uid":"foo", "equals":"version"}
|
||||
]
|
||||
*/
|
||||
void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char * keyName)
|
||||
void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char* keyName)
|
||||
{
|
||||
if(obj.contains(keyName))
|
||||
{
|
||||
if (obj.contains(keyName)) {
|
||||
auto reqArray = requireArray(obj, keyName);
|
||||
auto iter = reqArray.begin();
|
||||
while(iter != reqArray.end())
|
||||
{
|
||||
while (iter != reqArray.end()) {
|
||||
auto reqObject = requireObject(*iter);
|
||||
auto uid = requireString(reqObject, "uid");
|
||||
auto equals = ensureString(reqObject, "equals", QString());
|
||||
auto suggests = ensureString(reqObject, "suggests", QString());
|
||||
ptr->insert({uid, equals, suggests});
|
||||
ptr->insert({ uid, equals, suggests });
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char * keyName)
|
||||
void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char* keyName)
|
||||
{
|
||||
if(!ptr || ptr->empty())
|
||||
{
|
||||
if (!ptr || ptr->empty()) {
|
||||
return;
|
||||
}
|
||||
QJsonArray arrOut;
|
||||
for(auto &iter: *ptr)
|
||||
{
|
||||
for (auto& iter : *ptr) {
|
||||
QJsonObject reqOut;
|
||||
reqOut.insert("uid", iter.uid);
|
||||
if(!iter.equalsVersion.isEmpty())
|
||||
{
|
||||
if (!iter.equalsVersion.isEmpty()) {
|
||||
reqOut.insert("equals", iter.equalsVersion);
|
||||
}
|
||||
if(!iter.suggests.isEmpty())
|
||||
{
|
||||
if (!iter.suggests.isEmpty()) {
|
||||
reqOut.insert("suggests", iter.suggests);
|
||||
}
|
||||
arrOut.append(reqOut);
|
||||
@ -213,5 +194,4 @@ void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char * keyName)
|
||||
obj.insert(keyName, arrOut);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace Meta
|
||||
|
@ -18,43 +18,25 @@
|
||||
#include <QJsonObject>
|
||||
#include <memory>
|
||||
|
||||
#include <set>
|
||||
#include "Exception.h"
|
||||
#include "meta/BaseEntity.h"
|
||||
#include <set>
|
||||
|
||||
namespace Meta
|
||||
{
|
||||
namespace Meta {
|
||||
class Index;
|
||||
class Version;
|
||||
class VersionList;
|
||||
|
||||
enum class MetadataVersion
|
||||
{
|
||||
Invalid = -1,
|
||||
InitialRelease = 1
|
||||
};
|
||||
enum class MetadataVersion { Invalid = -1, InitialRelease = 1 };
|
||||
|
||||
class ParseException : public Exception
|
||||
{
|
||||
public:
|
||||
class ParseException : public Exception {
|
||||
public:
|
||||
using Exception::Exception;
|
||||
};
|
||||
struct Require
|
||||
{
|
||||
bool operator==(const Require & rhs) const
|
||||
{
|
||||
return uid == rhs.uid;
|
||||
}
|
||||
bool operator<(const Require & rhs) const
|
||||
{
|
||||
return uid < rhs.uid;
|
||||
}
|
||||
bool deepEquals(const Require & rhs) const
|
||||
{
|
||||
return uid == rhs.uid
|
||||
&& equalsVersion == rhs.equalsVersion
|
||||
&& suggests == rhs.suggests;
|
||||
}
|
||||
struct Require {
|
||||
bool operator==(const Require& rhs) const { return uid == rhs.uid; }
|
||||
bool operator<(const Require& rhs) const { return uid < rhs.uid; }
|
||||
bool deepEquals(const Require& rhs) const { return uid == rhs.uid && equalsVersion == rhs.equalsVersion && suggests == rhs.suggests; }
|
||||
QString uid;
|
||||
QString equalsVersion;
|
||||
QString suggests;
|
||||
@ -62,17 +44,17 @@ struct Require
|
||||
|
||||
using RequireSet = std::set<Require>;
|
||||
|
||||
void parseIndex(const QJsonObject &obj, Index *ptr);
|
||||
void parseVersion(const QJsonObject &obj, Version *ptr);
|
||||
void parseVersionList(const QJsonObject &obj, VersionList *ptr);
|
||||
void parseIndex(const QJsonObject& obj, Index* ptr);
|
||||
void parseVersion(const QJsonObject& obj, Version* ptr);
|
||||
void parseVersionList(const QJsonObject& obj, VersionList* ptr);
|
||||
|
||||
MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required = true);
|
||||
void serializeFormatVersion(QJsonObject &obj, MetadataVersion version);
|
||||
MetadataVersion parseFormatVersion(const QJsonObject& obj, bool required = true);
|
||||
void serializeFormatVersion(QJsonObject& obj, MetadataVersion version);
|
||||
|
||||
// FIXME: this has a different shape than the others...FIX IT!?
|
||||
void parseRequires(const QJsonObject &obj, RequireSet * ptr, const char * keyName = "requires");
|
||||
void serializeRequires(QJsonObject & objOut, RequireSet* ptr, const char * keyName = "requires");
|
||||
void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char* keyName = "requires");
|
||||
void serializeRequires(QJsonObject& objOut, RequireSet* ptr, const char* keyName = "requires");
|
||||
MetadataVersion currentFormatVersion();
|
||||
}
|
||||
} // namespace Meta
|
||||
|
||||
Q_DECLARE_METATYPE(std::set<Meta::Require>)
|
||||
|
@ -20,14 +20,9 @@
|
||||
#include "JsonFormat.h"
|
||||
#include "minecraft/PackProfile.h"
|
||||
|
||||
Meta::Version::Version(const QString &uid, const QString &version)
|
||||
: BaseVersion(), m_uid(uid), m_version(version)
|
||||
{
|
||||
}
|
||||
Meta::Version::Version(const QString& uid, const QString& version) : BaseVersion(), m_uid(uid), m_version(version) {}
|
||||
|
||||
Meta::Version::~Version()
|
||||
{
|
||||
}
|
||||
Meta::Version::~Version() {}
|
||||
|
||||
QString Meta::Version::descriptor()
|
||||
{
|
||||
@ -35,7 +30,7 @@ QString Meta::Version::descriptor()
|
||||
}
|
||||
QString Meta::Version::name()
|
||||
{
|
||||
if(m_data)
|
||||
if (m_data)
|
||||
return m_data->name;
|
||||
return m_uid;
|
||||
}
|
||||
@ -56,40 +51,32 @@ void Meta::Version::parse(const QJsonObject& obj)
|
||||
|
||||
void Meta::Version::mergeFromList(const Meta::Version::Ptr& other)
|
||||
{
|
||||
if(other->m_providesRecommendations)
|
||||
{
|
||||
if(m_recommended != other->m_recommended)
|
||||
{
|
||||
if (other->m_providesRecommendations) {
|
||||
if (m_recommended != other->m_recommended) {
|
||||
setRecommended(other->m_recommended);
|
||||
}
|
||||
}
|
||||
if (m_type != other->m_type)
|
||||
{
|
||||
if (m_type != other->m_type) {
|
||||
setType(other->m_type);
|
||||
}
|
||||
if (m_time != other->m_time)
|
||||
{
|
||||
if (m_time != other->m_time) {
|
||||
setTime(other->m_time);
|
||||
}
|
||||
if (m_requires != other->m_requires)
|
||||
{
|
||||
if (m_requires != other->m_requires) {
|
||||
m_requires = other->m_requires;
|
||||
}
|
||||
if (m_conflicts != other->m_conflicts)
|
||||
{
|
||||
if (m_conflicts != other->m_conflicts) {
|
||||
m_conflicts = other->m_conflicts;
|
||||
}
|
||||
if(m_volatile != other->m_volatile)
|
||||
{
|
||||
if (m_volatile != other->m_volatile) {
|
||||
setVolatile(other->m_volatile);
|
||||
}
|
||||
}
|
||||
|
||||
void Meta::Version::merge(const Version::Ptr &other)
|
||||
void Meta::Version::merge(const Version::Ptr& other)
|
||||
{
|
||||
mergeFromList(other);
|
||||
if(other->m_data)
|
||||
{
|
||||
if (other->m_data) {
|
||||
setData(other->m_data);
|
||||
}
|
||||
}
|
||||
@ -104,7 +91,7 @@ QString Meta::Version::localFilename() const
|
||||
return { const_cast<Meta::Version*>(this)->descriptor() };
|
||||
}
|
||||
|
||||
void Meta::Version::setType(const QString &type)
|
||||
void Meta::Version::setType(const QString& type)
|
||||
{
|
||||
m_type = type;
|
||||
emit typeChanged();
|
||||
@ -116,7 +103,7 @@ void Meta::Version::setTime(const qint64 time)
|
||||
emit timeChanged();
|
||||
}
|
||||
|
||||
void Meta::Version::setRequires(const Meta::RequireSet &reqs, const Meta::RequireSet &conflicts)
|
||||
void Meta::Version::setRequires(const Meta::RequireSet& reqs, const Meta::RequireSet& conflicts)
|
||||
{
|
||||
m_requires = reqs;
|
||||
m_conflicts = conflicts;
|
||||
@ -128,8 +115,7 @@ void Meta::Version::setVolatile(bool volatile_)
|
||||
m_volatile = volatile_;
|
||||
}
|
||||
|
||||
|
||||
void Meta::Version::setData(const VersionFilePtr &data)
|
||||
void Meta::Version::setData(const VersionFilePtr& data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
|
@ -15,8 +15,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseVersion.h"
|
||||
#include "../Version.h"
|
||||
#include "BaseVersion.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QStringList>
|
||||
@ -29,80 +29,54 @@
|
||||
|
||||
#include "JsonFormat.h"
|
||||
|
||||
namespace Meta
|
||||
{
|
||||
namespace Meta {
|
||||
|
||||
class Version : public QObject, public BaseVersion, public BaseEntity
|
||||
{
|
||||
class Version : public QObject, public BaseVersion, public BaseEntity {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
using Ptr = std::shared_ptr<Version>;
|
||||
|
||||
explicit Version(const QString &uid, const QString &version);
|
||||
explicit Version(const QString& uid, const QString& version);
|
||||
virtual ~Version();
|
||||
|
||||
QString descriptor() override;
|
||||
QString name() override;
|
||||
QString typeString() const override;
|
||||
|
||||
QString uid() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
QString version() const
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
QString type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
QString uid() const { return m_uid; }
|
||||
QString version() const { return m_version; }
|
||||
QString type() const { return m_type; }
|
||||
QDateTime time() const;
|
||||
qint64 rawTime() const
|
||||
{
|
||||
return m_time;
|
||||
}
|
||||
const Meta::RequireSet &requiredSet() const
|
||||
{
|
||||
return m_requires;
|
||||
}
|
||||
VersionFilePtr data() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
bool isRecommended() const
|
||||
{
|
||||
return m_recommended;
|
||||
}
|
||||
bool isLoaded() const
|
||||
{
|
||||
return m_data != nullptr;
|
||||
}
|
||||
qint64 rawTime() const { return m_time; }
|
||||
const Meta::RequireSet& requiredSet() const { return m_requires; }
|
||||
VersionFilePtr data() const { return m_data; }
|
||||
bool isRecommended() const { return m_recommended; }
|
||||
bool isLoaded() const { return m_data != nullptr; }
|
||||
|
||||
void merge(const Version::Ptr &other);
|
||||
void mergeFromList(const Version::Ptr &other);
|
||||
void parse(const QJsonObject &obj) override;
|
||||
void merge(const Version::Ptr& other);
|
||||
void mergeFromList(const Version::Ptr& other);
|
||||
void parse(const QJsonObject& obj) override;
|
||||
|
||||
QString localFilename() const override;
|
||||
|
||||
[[nodiscard]] ::Version toComparableVersion() const;
|
||||
|
||||
public: // for usage by format parsers only
|
||||
void setType(const QString &type);
|
||||
public: // for usage by format parsers only
|
||||
void setType(const QString& type);
|
||||
void setTime(const qint64 time);
|
||||
void setRequires(const Meta::RequireSet &reqs, const Meta::RequireSet &conflicts);
|
||||
void setRequires(const Meta::RequireSet& reqs, const Meta::RequireSet& conflicts);
|
||||
void setVolatile(bool volatile_);
|
||||
void setRecommended(bool recommended);
|
||||
void setProvidesRecommendations();
|
||||
void setData(const VersionFilePtr &data);
|
||||
void setData(const VersionFilePtr& data);
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void typeChanged();
|
||||
void timeChanged();
|
||||
void requiresChanged();
|
||||
|
||||
private:
|
||||
private:
|
||||
bool m_providesRecommendations = false;
|
||||
bool m_recommended = false;
|
||||
QString m_name;
|
||||
@ -115,6 +89,6 @@ private:
|
||||
bool m_volatile = false;
|
||||
VersionFilePtr m_data;
|
||||
};
|
||||
}
|
||||
} // namespace Meta
|
||||
|
||||
Q_DECLARE_METATYPE(Meta::Version::Ptr)
|
||||
|
@ -17,14 +17,11 @@
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
#include "Version.h"
|
||||
#include "JsonFormat.h"
|
||||
#include "Version.h"
|
||||
|
||||
namespace Meta
|
||||
{
|
||||
VersionList::VersionList(const QString &uid, QObject *parent)
|
||||
: BaseVersionList(parent), m_uid(uid)
|
||||
namespace Meta {
|
||||
VersionList::VersionList(const QString& uid, QObject* parent) : BaseVersionList(parent), m_uid(uid)
|
||||
{
|
||||
setObjectName("Version list: " + uid);
|
||||
}
|
||||
@ -52,61 +49,60 @@ int VersionList::count() const
|
||||
void VersionList::sortVersions()
|
||||
{
|
||||
beginResetModel();
|
||||
std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b)
|
||||
{
|
||||
return *a.get() < *b.get();
|
||||
});
|
||||
std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr& a, const Version::Ptr& b) { return *a.get() < *b.get(); });
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QVariant VersionList::data(const QModelIndex &index, int role) const
|
||||
QVariant VersionList::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= m_versions.size() || index.parent().isValid())
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= m_versions.size() || index.parent().isValid()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
Version::Ptr version = m_versions.at(index.row());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case VersionPointerRole: return QVariant::fromValue(std::dynamic_pointer_cast<BaseVersion>(version));
|
||||
case VersionRole:
|
||||
case VersionIdRole:
|
||||
return version->version();
|
||||
case ParentVersionRole:
|
||||
{
|
||||
// FIXME: HACK: this should be generic and be replaced by something else. Anything that is a hard 'equals' dep is a 'parent uid'.
|
||||
auto & reqs = version->requiredSet();
|
||||
auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Require & req)
|
||||
{
|
||||
return req.uid == "net.minecraft";
|
||||
});
|
||||
if (iter != reqs.end())
|
||||
{
|
||||
return (*iter).equalsVersion;
|
||||
switch (role) {
|
||||
case VersionPointerRole:
|
||||
return QVariant::fromValue(std::dynamic_pointer_cast<BaseVersion>(version));
|
||||
case VersionRole:
|
||||
case VersionIdRole:
|
||||
return version->version();
|
||||
case ParentVersionRole: {
|
||||
// FIXME: HACK: this should be generic and be replaced by something else. Anything that is a hard 'equals' dep is a 'parent
|
||||
// uid'.
|
||||
auto& reqs = version->requiredSet();
|
||||
auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Require& req) { return req.uid == "net.minecraft"; });
|
||||
if (iter != reqs.end()) {
|
||||
return (*iter).equalsVersion;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
case TypeRole: return version->type();
|
||||
case TypeRole:
|
||||
return version->type();
|
||||
|
||||
case UidRole: return version->uid();
|
||||
case TimeRole: return version->time();
|
||||
case RequiresRole: return QVariant::fromValue(version->requiredSet());
|
||||
case SortRole: return version->rawTime();
|
||||
case VersionPtrRole: return QVariant::fromValue(version);
|
||||
case RecommendedRole: return version->isRecommended();
|
||||
// FIXME: this should be determined in whatever view/proxy is used...
|
||||
// case LatestRole: return version == getLatestStable();
|
||||
default: return QVariant();
|
||||
case UidRole:
|
||||
return version->uid();
|
||||
case TimeRole:
|
||||
return version->time();
|
||||
case RequiresRole:
|
||||
return QVariant::fromValue(version->requiredSet());
|
||||
case SortRole:
|
||||
return version->rawTime();
|
||||
case VersionPtrRole:
|
||||
return QVariant::fromValue(version);
|
||||
case RecommendedRole:
|
||||
return version->isRecommended();
|
||||
// FIXME: this should be determined in whatever view/proxy is used...
|
||||
// case LatestRole: return version == getLatestStable();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
BaseVersionList::RoleList VersionList::providesRoles() const
|
||||
{
|
||||
return {VersionPointerRole, VersionRole, VersionIdRole, ParentVersionRole,
|
||||
TypeRole, UidRole, TimeRole, RequiresRole, SortRole,
|
||||
RecommendedRole, LatestRole, VersionPtrRole};
|
||||
return { VersionPointerRole, VersionRole, VersionIdRole, ParentVersionRole, TypeRole, UidRole,
|
||||
TimeRole, RequiresRole, SortRole, RecommendedRole, LatestRole, VersionPtrRole };
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> VersionList::roleNames() const
|
||||
@ -129,11 +125,10 @@ QString VersionList::humanReadable() const
|
||||
return m_name.isEmpty() ? m_uid : m_name;
|
||||
}
|
||||
|
||||
Version::Ptr VersionList::getVersion(const QString &version)
|
||||
Version::Ptr VersionList::getVersion(const QString& version)
|
||||
{
|
||||
Version::Ptr out = m_lookup.value(version, nullptr);
|
||||
if(!out)
|
||||
{
|
||||
if (!out) {
|
||||
out = std::make_shared<Version>(m_uid, version);
|
||||
m_lookup[version] = out;
|
||||
}
|
||||
@ -142,33 +137,31 @@ Version::Ptr VersionList::getVersion(const QString &version)
|
||||
|
||||
bool VersionList::hasVersion(QString version) const
|
||||
{
|
||||
auto ver = std::find_if(m_versions.constBegin(), m_versions.constEnd(),
|
||||
[&](Meta::Version::Ptr const& a){ return a->version() == version; });
|
||||
auto ver =
|
||||
std::find_if(m_versions.constBegin(), m_versions.constEnd(), [&](Meta::Version::Ptr const& a) { return a->version() == version; });
|
||||
return (ver != m_versions.constEnd());
|
||||
}
|
||||
|
||||
void VersionList::setName(const QString &name)
|
||||
void VersionList::setName(const QString& name)
|
||||
{
|
||||
m_name = name;
|
||||
emit nameChanged(name);
|
||||
}
|
||||
|
||||
void VersionList::setVersions(const QVector<Version::Ptr> &versions)
|
||||
void VersionList::setVersions(const QVector<Version::Ptr>& versions)
|
||||
{
|
||||
beginResetModel();
|
||||
m_versions = versions;
|
||||
std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b)
|
||||
{
|
||||
return a->rawTime() > b->rawTime();
|
||||
});
|
||||
for (int i = 0; i < m_versions.size(); ++i)
|
||||
{
|
||||
std::sort(m_versions.begin(), m_versions.end(),
|
||||
[](const Version::Ptr& a, const Version::Ptr& b) { return a->rawTime() > b->rawTime(); });
|
||||
for (int i = 0; i < m_versions.size(); ++i) {
|
||||
m_lookup.insert(m_versions.at(i)->version(), m_versions.at(i));
|
||||
setupAddedVersion(i, m_versions.at(i));
|
||||
}
|
||||
|
||||
// FIXME: this is dumb, we have 'recommended' as part of the metadata already...
|
||||
auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const Version::Ptr &ptr) { return ptr->type() == "release"; });
|
||||
auto recommendedIt =
|
||||
std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const Version::Ptr& ptr) { return ptr->type() == "release"; });
|
||||
m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt;
|
||||
endResetModel();
|
||||
}
|
||||
@ -179,14 +172,13 @@ void VersionList::parse(const QJsonObject& obj)
|
||||
}
|
||||
|
||||
// FIXME: this is dumb, we have 'recommended' as part of the metadata already...
|
||||
static const Meta::Version::Ptr &getBetterVersion(const Meta::Version::Ptr &a, const Meta::Version::Ptr &b)
|
||||
static const Meta::Version::Ptr& getBetterVersion(const Meta::Version::Ptr& a, const Meta::Version::Ptr& b)
|
||||
{
|
||||
if(!a)
|
||||
if (!a)
|
||||
return b;
|
||||
if(!b)
|
||||
if (!b)
|
||||
return a;
|
||||
if(a->type() == b->type())
|
||||
{
|
||||
if (a->type() == b->type()) {
|
||||
// newer of same type wins
|
||||
return (a->rawTime() > b->rawTime() ? a : b);
|
||||
}
|
||||
@ -194,37 +186,30 @@ static const Meta::Version::Ptr &getBetterVersion(const Meta::Version::Ptr &a, c
|
||||
return (a->type() == "release" ? a : b);
|
||||
}
|
||||
|
||||
void VersionList::mergeFromIndex(const VersionList::Ptr &other)
|
||||
void VersionList::mergeFromIndex(const VersionList::Ptr& other)
|
||||
{
|
||||
if (m_name != other->m_name)
|
||||
{
|
||||
if (m_name != other->m_name) {
|
||||
setName(other->m_name);
|
||||
}
|
||||
}
|
||||
|
||||
void VersionList::merge(const VersionList::Ptr &other)
|
||||
void VersionList::merge(const VersionList::Ptr& other)
|
||||
{
|
||||
if (m_name != other->m_name)
|
||||
{
|
||||
if (m_name != other->m_name) {
|
||||
setName(other->m_name);
|
||||
}
|
||||
|
||||
// TODO: do not reset the whole model. maybe?
|
||||
beginResetModel();
|
||||
m_versions.clear();
|
||||
if(other->m_versions.isEmpty())
|
||||
{
|
||||
if (other->m_versions.isEmpty()) {
|
||||
qWarning() << "Empty list loaded ...";
|
||||
}
|
||||
for (const Version::Ptr &version : other->m_versions)
|
||||
{
|
||||
for (const Version::Ptr& version : other->m_versions) {
|
||||
// we already have the version. merge the contents
|
||||
if (m_lookup.contains(version->version()))
|
||||
{
|
||||
if (m_lookup.contains(version->version())) {
|
||||
m_lookup.value(version->version())->mergeFromList(version);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_lookup.insert(version->uid(), version);
|
||||
}
|
||||
// connect it.
|
||||
@ -235,13 +220,16 @@ void VersionList::merge(const VersionList::Ptr &other)
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void VersionList::setupAddedVersion(const int row, const Version::Ptr &version)
|
||||
void VersionList::setupAddedVersion(const int row, const Version::Ptr& version)
|
||||
{
|
||||
// FIXME: do not disconnect from everythin, disconnect only the lambdas here
|
||||
version->disconnect();
|
||||
connect(version.get(), &Version::requiresChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << RequiresRole); });
|
||||
connect(version.get(), &Version::timeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TimeRole << SortRole); });
|
||||
connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TypeRole); });
|
||||
connect(version.get(), &Version::requiresChanged, this,
|
||||
[this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << RequiresRole); });
|
||||
connect(version.get(), &Version::timeChanged, this,
|
||||
[this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TimeRole << SortRole); });
|
||||
connect(version.get(), &Version::typeChanged, this,
|
||||
[this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TypeRole); });
|
||||
}
|
||||
|
||||
BaseVersion::Ptr VersionList::getRecommended() const
|
||||
@ -249,4 +237,4 @@ BaseVersion::Ptr VersionList::getRecommended() const
|
||||
return m_recommended;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Meta
|
||||
|
@ -15,33 +15,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseEntity.h"
|
||||
#include "BaseVersionList.h"
|
||||
#include <QJsonObject>
|
||||
#include <memory>
|
||||
#include "BaseEntity.h"
|
||||
#include "BaseVersionList.h"
|
||||
|
||||
#include "meta/Version.h"
|
||||
|
||||
namespace Meta
|
||||
{
|
||||
namespace Meta {
|
||||
|
||||
class VersionList : public BaseVersionList, public BaseEntity
|
||||
{
|
||||
class VersionList : public BaseVersionList, public BaseEntity {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString uid READ uid CONSTANT)
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
public:
|
||||
explicit VersionList(const QString &uid, QObject *parent = nullptr);
|
||||
public:
|
||||
explicit VersionList(const QString& uid, QObject* parent = nullptr);
|
||||
|
||||
using Ptr = std::shared_ptr<VersionList>;
|
||||
|
||||
enum Roles
|
||||
{
|
||||
UidRole = Qt::UserRole + 100,
|
||||
TimeRole,
|
||||
RequiresRole,
|
||||
VersionPtrRole
|
||||
};
|
||||
enum Roles { UidRole = Qt::UserRole + 100, TimeRole, RequiresRole, VersionPtrRole };
|
||||
|
||||
Task::Ptr getLoadTask() override;
|
||||
bool isLoaded() override;
|
||||
@ -51,46 +43,35 @@ public:
|
||||
|
||||
BaseVersion::Ptr getRecommended() const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant data(const QModelIndex& index, int role) const override;
|
||||
RoleList providesRoles() const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
QString localFilename() const override;
|
||||
|
||||
QString uid() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
QString name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
QString uid() const { return m_uid; }
|
||||
QString name() const { return m_name; }
|
||||
QString humanReadable() const;
|
||||
|
||||
Version::Ptr getVersion(const QString &version);
|
||||
Version::Ptr getVersion(const QString& version);
|
||||
bool hasVersion(QString version) const;
|
||||
|
||||
QVector<Version::Ptr> versions() const
|
||||
{
|
||||
return m_versions;
|
||||
}
|
||||
QVector<Version::Ptr> versions() const { return m_versions; }
|
||||
|
||||
public: // for usage only by parsers
|
||||
void setName(const QString &name);
|
||||
void setVersions(const QVector<Version::Ptr> &versions);
|
||||
void merge(const VersionList::Ptr &other);
|
||||
void mergeFromIndex(const VersionList::Ptr &other);
|
||||
void parse(const QJsonObject &obj) override;
|
||||
public: // for usage only by parsers
|
||||
void setName(const QString& name);
|
||||
void setVersions(const QVector<Version::Ptr>& versions);
|
||||
void merge(const VersionList::Ptr& other);
|
||||
void mergeFromIndex(const VersionList::Ptr& other);
|
||||
void parse(const QJsonObject& obj) override;
|
||||
|
||||
signals:
|
||||
void nameChanged(const QString &name);
|
||||
signals:
|
||||
void nameChanged(const QString& name);
|
||||
|
||||
protected slots:
|
||||
void updateListData(QList<BaseVersion::Ptr>) override
|
||||
{
|
||||
}
|
||||
protected slots:
|
||||
void updateListData(QList<BaseVersion::Ptr>) override {}
|
||||
|
||||
private:
|
||||
private:
|
||||
QVector<Version::Ptr> m_versions;
|
||||
QHash<QString, Version::Ptr> m_lookup;
|
||||
QString m_uid;
|
||||
@ -98,7 +79,7 @@ private:
|
||||
|
||||
Version::Ptr m_recommended;
|
||||
|
||||
void setupAddedVersion(const int row, const Version::Ptr &version);
|
||||
void setupAddedVersion(const int row, const Version::Ptr& version);
|
||||
};
|
||||
}
|
||||
} // namespace Meta
|
||||
Q_DECLARE_METATYPE(Meta::VersionList::Ptr)
|
||||
|
Reference in New Issue
Block a user