diff options
author | Petr Mrázek <peterix@gmail.com> | 2016-04-10 17:01:24 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2016-05-01 00:00:24 +0200 |
commit | 1be7d573326570d63e55e36235537ed2b1831ae1 (patch) | |
tree | ba7037671cde8688e87e69acb753df80ec4cd4f9 /api/logic | |
parent | aa4842a91d35481264ae5a7c0ac17ea43610b600 (diff) | |
download | MultiMC-1be7d573326570d63e55e36235537ed2b1831ae1.tar MultiMC-1be7d573326570d63e55e36235537ed2b1831ae1.tar.gz MultiMC-1be7d573326570d63e55e36235537ed2b1831ae1.tar.lz MultiMC-1be7d573326570d63e55e36235537ed2b1831ae1.tar.xz MultiMC-1be7d573326570d63e55e36235537ed2b1831ae1.zip |
NOISSUE re/move some dead code and unused build system parts
Diffstat (limited to 'api/logic')
-rw-r--r-- | api/logic/AbstractCommonModel.cpp | 133 | ||||
-rw-r--r-- | api/logic/AbstractCommonModel.h | 462 | ||||
-rw-r--r-- | api/logic/BaseConfigObject.cpp | 103 | ||||
-rw-r--r-- | api/logic/BaseConfigObject.h | 50 | ||||
-rw-r--r-- | api/logic/CMakeLists.txt | 15 | ||||
-rw-r--r-- | api/logic/TypeMagic.h | 37 | ||||
-rw-r--r-- | api/logic/resources/Resource.cpp | 155 | ||||
-rw-r--r-- | api/logic/resources/Resource.h | 132 | ||||
-rw-r--r-- | api/logic/resources/ResourceHandler.cpp | 28 | ||||
-rw-r--r-- | api/logic/resources/ResourceHandler.h | 36 | ||||
-rw-r--r-- | api/logic/resources/ResourceObserver.cpp | 55 | ||||
-rw-r--r-- | api/logic/resources/ResourceObserver.h | 73 | ||||
-rw-r--r-- | api/logic/resources/ResourceProxyModel.cpp | 89 | ||||
-rw-r--r-- | api/logic/resources/ResourceProxyModel.h | 39 |
14 files changed, 0 insertions, 1407 deletions
diff --git a/api/logic/AbstractCommonModel.cpp b/api/logic/AbstractCommonModel.cpp deleted file mode 100644 index 71d75829..00000000 --- a/api/logic/AbstractCommonModel.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright 2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AbstractCommonModel.h" - -BaseAbstractCommonModel::BaseAbstractCommonModel(const Qt::Orientation orientation, QObject *parent) - : QAbstractListModel(parent), m_orientation(orientation) -{ -} - -int BaseAbstractCommonModel::rowCount(const QModelIndex &parent) const -{ - return m_orientation == Qt::Horizontal ? entryCount() : size(); -} -int BaseAbstractCommonModel::columnCount(const QModelIndex &parent) const -{ - return m_orientation == Qt::Horizontal ? size() : entryCount(); -} -QVariant BaseAbstractCommonModel::data(const QModelIndex &index, int role) const -{ - if (!hasIndex(index.row(), index.column(), index.parent())) - { - return QVariant(); - } - const int i = m_orientation == Qt::Horizontal ? index.column() : index.row(); - const int entry = m_orientation == Qt::Horizontal ? index.row() : index.column(); - return formatData(i, role, get(i, entry, role)); -} -QVariant BaseAbstractCommonModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation != m_orientation && role == Qt::DisplayRole) - { - return entryTitle(section); - } - else - { - return QVariant(); - } -} -bool BaseAbstractCommonModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - const int i = m_orientation == Qt::Horizontal ? index.column() : index.row(); - const int entry = m_orientation == Qt::Horizontal ? index.row() : index.column(); - const bool result = set(i, entry, role, sanetizeData(i, role, value)); - if (result) - { - emit dataChanged(index, index, QVector<int>() << role); - } - return result; -} -Qt::ItemFlags BaseAbstractCommonModel::flags(const QModelIndex &index) const -{ - if (!hasIndex(index.row(), index.column(), index.parent())) - { - return Qt::NoItemFlags; - } - - const int entry = m_orientation == Qt::Horizontal ? index.row() : index.column(); - if (canSet(entry)) - { - return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled; - } - else - { - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; - } -} - -void BaseAbstractCommonModel::notifyAboutToAddObject(const int at) -{ - if (m_orientation == Qt::Horizontal) - { - beginInsertColumns(QModelIndex(), at, at); - } - else - { - beginInsertRows(QModelIndex(), at, at); - } -} -void BaseAbstractCommonModel::notifyObjectAdded() -{ - if (m_orientation == Qt::Horizontal) - { - endInsertColumns(); - } - else - { - endInsertRows(); - } -} -void BaseAbstractCommonModel::notifyAboutToRemoveObject(const int at) -{ - if (m_orientation == Qt::Horizontal) - { - beginRemoveColumns(QModelIndex(), at, at); - } - else - { - beginRemoveRows(QModelIndex(), at, at); - } -} -void BaseAbstractCommonModel::notifyObjectRemoved() -{ - if (m_orientation == Qt::Horizontal) - { - endRemoveColumns(); - } - else - { - endRemoveRows(); - } -} - -void BaseAbstractCommonModel::notifyBeginReset() -{ - beginResetModel(); -} -void BaseAbstractCommonModel::notifyEndReset() -{ - endResetModel(); -} diff --git a/api/logic/AbstractCommonModel.h b/api/logic/AbstractCommonModel.h deleted file mode 100644 index 31b86a23..00000000 --- a/api/logic/AbstractCommonModel.h +++ /dev/null @@ -1,462 +0,0 @@ -/* Copyright 2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <QAbstractListModel> -#include <type_traits> -#include <functional> -#include <memory> - -class BaseAbstractCommonModel : public QAbstractListModel -{ - Q_OBJECT -public: - explicit BaseAbstractCommonModel(const Qt::Orientation orientation, QObject *parent = nullptr); - - // begin QAbstractItemModel interface - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role) override; - Qt::ItemFlags flags(const QModelIndex &index) const override; - // end QAbstractItemModel interface - - virtual int size() const = 0; - virtual int entryCount() const = 0; - - virtual QVariant formatData(const int index, int role, const QVariant &data) const { return data; } - virtual QVariant sanetizeData(const int index, int role, const QVariant &data) const { return data; } - -protected: - virtual QVariant get(const int index, const int entry, const int role) const = 0; - virtual bool set(const int index, const int entry, const int role, const QVariant &value) = 0; - virtual bool canSet(const int entry) const = 0; - virtual QString entryTitle(const int entry) const = 0; - - void notifyAboutToAddObject(const int at); - void notifyObjectAdded(); - void notifyAboutToRemoveObject(const int at); - void notifyObjectRemoved(); - void notifyBeginReset(); - void notifyEndReset(); - - const Qt::Orientation m_orientation; -}; - -template<typename Object> -class AbstractCommonModel : public BaseAbstractCommonModel -{ -public: - explicit AbstractCommonModel(const Qt::Orientation orientation) - : BaseAbstractCommonModel(orientation) {} - virtual ~AbstractCommonModel() {} - - int size() const override { return m_objects.size(); } - int entryCount() const override { return m_entries.size(); } - - void append(const Object &object) - { - notifyAboutToAddObject(size()); - m_objects.append(object); - notifyObjectAdded(); - } - void prepend(const Object &object) - { - notifyAboutToAddObject(0); - m_objects.prepend(object); - notifyObjectAdded(); - } - void insert(const Object &object, const int index) - { - if (index >= size()) - { - prepend(object); - } - else if (index <= 0) - { - append(object); - } - else - { - notifyAboutToAddObject(index); - m_objects.insert(index, object); - notifyObjectAdded(); - } - } - void remove(const int index) - { - notifyAboutToRemoveObject(index); - m_objects.removeAt(index); - notifyObjectRemoved(); - } - Object get(const int index) const - { - return m_objects.at(index); - } - -private: - friend class CommonModel; - QVariant get(const int index, const int entry, const int role) const override - { - if (m_entries.size() < entry || !m_entries[entry].second.contains(role)) - { - return QVariant(); - } - return m_entries[entry].second.value(role)->get(m_objects.at(index)); - } - bool set(const int index, const int entry, const int role, const QVariant &value) override - { - if (m_entries.size() < entry || !m_entries[entry].second.contains(role)) - { - return false; - } - IEntry *e = m_entries[entry].second.value(role); - if (!e->canSet()) - { - return false; - } - e->set(m_objects[index], value); - return true; - } - bool canSet(const int entry) const override - { - if (m_entries.size() < entry || !m_entries[entry].second.contains(Qt::EditRole)) - { - return false; - } - IEntry *e = m_entries[entry].second.value(Qt::EditRole); - return e->canSet(); - } - - QString entryTitle(const int entry) const override - { - return m_entries.at(entry).first; - } - -private: - struct IEntry - { - virtual ~IEntry() {} - virtual void set(Object &object, const QVariant &value) = 0; - virtual QVariant get(const Object &object) const = 0; - virtual bool canSet() const = 0; - }; - template<typename T> - struct VariableEntry : public IEntry - { - typedef T (Object::*Member); - - explicit VariableEntry(Member member) - : m_member(member) {} - - void set(Object &object, const QVariant &value) override - { - object.*m_member = value.value<T>(); - } - QVariant get(const Object &object) const override - { - return QVariant::fromValue<T>(object.*m_member); - } - bool canSet() const override { return true; } - - private: - Member m_member; - }; - template<typename T> - struct FunctionEntry : public IEntry - { - typedef T (Object::*Getter)() const; - typedef void (Object::*Setter)(T); - - explicit FunctionEntry(Getter getter, Setter setter) - : m_getter(m_getter), m_setter(m_setter) {} - - void set(Object &object, const QVariant &value) override - { - object.*m_setter(value.value<T>()); - } - QVariant get(const Object &object) const override - { - return QVariant::fromValue<T>(object.*m_getter()); - } - bool canSet() const override { return !!m_setter; } - - private: - Getter m_getter; - Setter m_setter; - }; - - QList<Object> m_objects; - QVector<QPair<QString, QMap<int, IEntry *>>> m_entries; - - void addEntryInternal(IEntry *e, const int entry, const int role) - { - if (m_entries.size() <= entry) - { - m_entries.resize(entry + 1); - } - m_entries[entry].second.insert(role, e); - } - -protected: - template<typename Getter, typename Setter> - typename std::enable_if<std::is_member_function_pointer<Getter>::value && std::is_member_function_pointer<Getter>::value, void>::type - addEntry(Getter getter, Setter setter, const int entry, const int role) - { - addEntryInternal(new FunctionEntry<typename std::result_of<Getter>::type>(getter, setter), entry, role); - } - template<typename Getter> - typename std::enable_if<std::is_member_function_pointer<Getter>::value, void>::type - addEntry(Getter getter, const int entry, const int role) - { - addEntryInternal(new FunctionEntry<typename std::result_of<Getter>::type>(getter, nullptr), entry, role); - } - template<typename T> - typename std::enable_if<!std::is_member_function_pointer<T (Object::*)>::value, void>::type - addEntry(T (Object::*member), const int entry, const int role) - { - addEntryInternal(new VariableEntry<T>(member), entry, role); - } - - void setEntryTitle(const int entry, const QString &title) - { - m_entries[entry].first = title; - } -}; -template<typename Object> -class AbstractCommonModel<Object *> : public BaseAbstractCommonModel -{ -public: - explicit AbstractCommonModel(const Qt::Orientation orientation) - : BaseAbstractCommonModel(orientation) {} - virtual ~AbstractCommonModel() - { - qDeleteAll(m_objects); - } - - int size() const override { return m_objects.size(); } - int entryCount() const override { return m_entries.size(); } - - void append(Object *object) - { - notifyAboutToAddObject(size()); - m_objects.append(object); - notifyObjectAdded(); - } - void prepend(Object *object) - { - notifyAboutToAddObject(0); - m_objects.prepend(object); - notifyObjectAdded(); - } - void insert(Object *object, const int index) - { - if (index >= size()) - { - prepend(object); - } - else if (index <= 0) - { - append(object); - } - else - { - notifyAboutToAddObject(index); - m_objects.insert(index, object); - notifyObjectAdded(); - } - } - void remove(const int index) - { - notifyAboutToRemoveObject(index); - m_objects.removeAt(index); - notifyObjectRemoved(); - } - Object *get(const int index) const - { - return m_objects.at(index); - } - int find(Object * const obj) const - { - return m_objects.indexOf(obj); - } - - QList<Object *> getAll() const - { - return m_objects; - } - -private: - friend class CommonModel; - QVariant get(const int index, const int entry, const int role) const override - { - if (m_entries.size() < entry || !m_entries[entry].second.contains(role)) - { - return QVariant(); - } - return m_entries[entry].second.value(role)->get(m_objects.at(index)); - } - bool set(const int index, const int entry, const int role, const QVariant &value) override - { - if (m_entries.size() < entry || !m_entries[entry].second.contains(role)) - { - return false; - } - IEntry *e = m_entries[entry].second.value(role); - if (!e->canSet()) - { - return false; - } - e->set(m_objects[index], value); - return true; - } - bool canSet(const int entry) const override - { - if (m_entries.size() < entry || !m_entries[entry].second.contains(Qt::EditRole)) - { - return false; - } - IEntry *e = m_entries[entry].second.value(Qt::EditRole); - return e->canSet(); - } - - QString entryTitle(const int entry) const override - { - return m_entries.at(entry).first; - } - -private: - struct IEntry - { - virtual ~IEntry() {} - virtual void set(Object *object, const QVariant &value) = 0; - virtual QVariant get(Object *object) const = 0; - virtual bool canSet() const = 0; - }; - template<typename T> - struct VariableEntry : public IEntry - { - typedef T (Object::*Member); - - explicit VariableEntry(Member member) - : m_member(member) {} - - void set(Object *object, const QVariant &value) override - { - object->*m_member = value.value<T>(); - } - QVariant get(Object *object) const override - { - return QVariant::fromValue<T>(object->*m_member); - } - bool canSet() const override { return true; } - - private: - Member m_member; - }; - template<typename T> - struct FunctionEntry : public IEntry - { - typedef T (Object::*Getter)() const; - typedef void (Object::*Setter)(T); - - explicit FunctionEntry(Getter getter, Setter setter) - : m_getter(getter), m_setter(setter) {} - - void set(Object *object, const QVariant &value) override - { - (object->*m_setter)(value.value<T>()); - } - QVariant get(Object *object) const override - { - return QVariant::fromValue<T>((object->*m_getter)()); - } - bool canSet() const override { return !!m_setter; } - - private: - Getter m_getter; - Setter m_setter; - }; - template<typename T> - struct LambdaEntry : public IEntry - { - using Getter = std::function<T(Object *)>; - - explicit LambdaEntry(Getter getter) - : m_getter(getter) {} - - void set(Object *object, const QVariant &value) override {} - QVariant get(Object *object) const override - { - return QVariant::fromValue<T>(m_getter(object)); - } - bool canSet() const override { return false; } - - private: - Getter m_getter; - }; - - QList<Object *> m_objects; - QVector<QPair<QString, QMap<int, IEntry *>>> m_entries; - - void addEntryInternal(IEntry *e, const int entry, const int role) - { - if (m_entries.size() <= entry) - { - m_entries.resize(entry + 1); - } - m_entries[entry].second.insert(role, e); - } - -protected: - template<typename Getter, typename Setter> - typename std::enable_if<std::is_member_function_pointer<Getter>::value && std::is_member_function_pointer<Getter>::value, void>::type - addEntry(const int entry, const int role, Getter getter, Setter setter) - { - addEntryInternal(new FunctionEntry<typename std::result_of<Getter>::type>(getter, setter), entry, role); - } - template<typename T> - typename std::enable_if<std::is_member_function_pointer<typename FunctionEntry<T>::Getter>::value, void>::type - addEntry(const int entry, const int role, typename FunctionEntry<T>::Getter getter) - { - addEntryInternal(new FunctionEntry<T>(getter, nullptr), entry, role); - } - template<typename T> - typename std::enable_if<!std::is_member_function_pointer<T (Object::*)>::value, void>::type - addEntry(const int entry, const int role, T (Object::*member)) - { - addEntryInternal(new VariableEntry<T>(member), entry, role); - } - template<typename T> - void addEntry(const int entry, const int role, typename LambdaEntry<T>::Getter lambda) - { - addEntryInternal(new LambdaEntry<T>(lambda), entry, role); - } - - void setEntryTitle(const int entry, const QString &title) - { - m_entries[entry].first = title; - } - - void setAll(const QList<Object *> objects) - { - notifyBeginReset(); - qDeleteAll(m_objects); - m_objects = objects; - notifyEndReset(); - } -}; diff --git a/api/logic/BaseConfigObject.cpp b/api/logic/BaseConfigObject.cpp deleted file mode 100644 index 3040ac2e..00000000 --- a/api/logic/BaseConfigObject.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright 2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "BaseConfigObject.h" - -#include <QTimer> -#include <QFile> -#include <QCoreApplication> -#include <QDebug> - -#include "Exception.h" -#include "FileSystem.h" - -BaseConfigObject::BaseConfigObject(const QString &filename) - : m_filename(filename) -{ - m_saveTimer = new QTimer; - m_saveTimer->setSingleShot(true); - // cppcheck-suppress pureVirtualCall - QObject::connect(m_saveTimer, &QTimer::timeout, [this](){saveNow();}); - setSaveTimeout(250); - - m_initialReadTimer = new QTimer; - m_initialReadTimer->setSingleShot(true); - QObject::connect(m_initialReadTimer, &QTimer::timeout, [this]() - { - loadNow(); - m_initialReadTimer->deleteLater(); - m_initialReadTimer = 0; - }); - m_initialReadTimer->start(0); - - // cppcheck-suppress pureVirtualCall - m_appQuitConnection = QObject::connect(qApp, &QCoreApplication::aboutToQuit, [this](){saveNow();}); -} -BaseConfigObject::~BaseConfigObject() -{ - delete m_saveTimer; - if (m_initialReadTimer) - { - delete m_initialReadTimer; - } - QObject::disconnect(m_appQuitConnection); -} - -void BaseConfigObject::setSaveTimeout(int msec) -{ - m_saveTimer->setInterval(msec); -} - -void BaseConfigObject::scheduleSave() -{ - m_saveTimer->stop(); - m_saveTimer->start(); -} -void BaseConfigObject::saveNow() -{ - if (m_saveTimer->isActive()) - { - m_saveTimer->stop(); - } - if (m_disableSaving) - { - return; - } - - try - { - FS::write(m_filename, doSave()); - } - catch (Exception & e) - { - qCritical() << e.cause(); - } -} -void BaseConfigObject::loadNow() -{ - if (m_saveTimer->isActive()) - { - saveNow(); - } - - try - { - doLoad(FS::read(m_filename)); - } - catch (Exception & e) - { - qWarning() << "Error loading" << m_filename << ":" << e.cause(); - } -} diff --git a/api/logic/BaseConfigObject.h b/api/logic/BaseConfigObject.h deleted file mode 100644 index 1c96b3d1..00000000 --- a/api/logic/BaseConfigObject.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <QObject> - -class QTimer; - -class BaseConfigObject -{ -public: - void setSaveTimeout(int msec); - -protected: - explicit BaseConfigObject(const QString &filename); - virtual ~BaseConfigObject(); - - // cppcheck-suppress pureVirtualCall - virtual QByteArray doSave() const = 0; - virtual void doLoad(const QByteArray &data) = 0; - - void setSavingDisabled(bool savingDisabled) { m_disableSaving = savingDisabled; } - - QString fileName() const { return m_filename; } - -public: - void scheduleSave(); - void saveNow(); - void loadNow(); - -private: - QTimer *m_saveTimer; - QTimer *m_initialReadTimer; - QString m_filename; - QMetaObject::Connection m_appQuitConnection; - bool m_disableSaving = false; -}; diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt index 317627d5..a7013c9d 100644 --- a/api/logic/CMakeLists.txt +++ b/api/logic/CMakeLists.txt @@ -16,11 +16,6 @@ set(LOGIC_SOURCES MMCZip.cpp MMCStrings.h MMCStrings.cpp - BaseConfigObject.h - BaseConfigObject.cpp - AbstractCommonModel.h - AbstractCommonModel.cpp - TypeMagic.h # Prefix tree where node names are strings between separators SeparatorPrefixTree.h @@ -47,16 +42,6 @@ set(LOGIC_SOURCES # a smart pointer wrapper intended for safer use with Qt signal/slot mechanisms QObjectPtr.h - # Resources - resources/Resource.cpp - resources/Resource.h - resources/ResourceHandler.cpp - resources/ResourceHandler.h - resources/ResourceObserver.cpp - resources/ResourceObserver.h - resources/ResourceProxyModel.h - resources/ResourceProxyModel.cpp - # Path matchers pathmatcher/FSTreeMatcher.h pathmatcher/IPathMatcher.h diff --git a/api/logic/TypeMagic.h b/api/logic/TypeMagic.h deleted file mode 100644 index fa9d12a9..00000000 --- a/api/logic/TypeMagic.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -namespace TypeMagic -{ -/** "Cleans" the given type T by stripping references (&) and cv-qualifiers (const, volatile) from it - * const int => int - * QString & => QString - * const unsigned long long & => unsigned long long - * - * Usage: - * using Cleaned = Detail::CleanType<const int>; - * static_assert(std::is_same<Cleaned, int>, "Cleaned == int"); - */ -// the order of remove_cv and remove_reference matters! -template <typename T> -using CleanType = typename std::remove_cv<typename std::remove_reference<T>::type>::type; - -/// For functors (structs with operator()), including lambdas, which in **most** cases are functors -/// "Calls" Function<Ret(*)(Arg)> or Function<Ret(C::*)(Arg)> -template <typename T> struct Function : public Function<decltype(&T::operator())> {}; -/// For function pointers (&function), including static members (&Class::member) -template <typename Ret, typename Arg> struct Function<Ret(*)(Arg)> : public Function<Ret(Arg)> {}; -/// Default specialization used by others. -template <typename Ret, typename Arg> struct Function<Ret(Arg)> -{ - using ReturnType = Ret; - using Argument = Arg; -}; -/// For member functions. Also used by the lambda overload if the lambda captures [this] -template <class C, typename Ret, typename Arg> struct Function<Ret(C::*)(Arg)> : public Function<Ret(Arg)> {}; -template <class C, typename Ret, typename Arg> struct Function<Ret(C::*)(Arg) const> : public Function<Ret(Arg)> {}; -/// Overload for references -template <typename F> struct Function<F&> : public Function<F> {}; -/// Overload for rvalues -template <typename F> struct Function<F&&> : public Function<F> {}; -// for more info: https://functionalcpp.wordpress.com/2013/08/05/function-traits/ -} diff --git a/api/logic/resources/Resource.cpp b/api/logic/resources/Resource.cpp deleted file mode 100644 index e95675d7..00000000 --- a/api/logic/resources/Resource.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include "Resource.h" - -#include <QDebug> - -#include "ResourceObserver.h" -#include "ResourceHandler.h" - -// definition of static members of Resource -QMap<QString, std::function<std::shared_ptr<ResourceHandler>(const QString &)>> Resource::m_handlers; -QMap<QPair<int, int>, std::function<QVariant(QVariant)>> Resource::m_transfomers; -QMap<QString, std::weak_ptr<Resource>> Resource::m_resources; - -struct NullResourceResult {}; -Q_DECLARE_METATYPE(NullResourceResult) -class NullResourceHandler : public ResourceHandler -{ -public: - explicit NullResourceHandler() - { - setResult(QVariant::fromValue<NullResourceResult>(NullResourceResult())); - } -}; - -Resource::Resource(const QString &resource) - : m_resource(resource) -{ - if (!resource.isEmpty()) - { - // a valid resource identifier has the format <id>:<data> - Q_ASSERT(resource.contains(':')); - // "parse" the resource identifier into id and data - const QString resourceId = resource.left(resource.indexOf(':')); - const QString resourceData = resource.mid(resource.indexOf(':') + 1); - - // create and set up the handler - Q_ASSERT(m_handlers.contains(resourceId)); - m_handler = m_handlers.value(resourceId)(resourceData); - } - else - { - m_handler = std::make_shared<NullResourceHandler>(); - } - - Q_ASSERT(m_handler); - m_handler->init(m_handler); - m_handler->setResource(this); -} -Resource::~Resource() -{ - qDeleteAll(m_observers); -} - -Resource::Ptr Resource::create(const QString &resource, Ptr placeholder) -{ - const QString storageId = storageIdentifier(resource, placeholder); - - // do we already have a resource? even if m_resources contains it it might not be valid any longer (weak_ptr) - Resource::Ptr ptr = m_resources.contains(storageId) - ? m_resources.value(storageId).lock() - : nullptr; - // did we have one? and is it still valid? - if (!ptr) - { - /* We don't want Resource to have a public constructor, but std::make_shared needs it, - * so we create a subclass of Resource here that exposes the constructor as public. - * The alternative would be making the allocator for std::make_shared a friend, but it - * differs between different STL implementations, so that would be a pain. - */ - struct ConstructableResource : public Resource - { - explicit ConstructableResource(const QString &resource) - : Resource(resource) {} - }; - ptr = std::make_shared<ConstructableResource>(resource); - ptr->m_placeholder = placeholder; - m_resources.insert(storageId, ptr); - } - return ptr; -} - -Resource::Ptr Resource::applyTo(ResourceObserver *observer) -{ - m_observers.append(observer); - observer->setSource(shared_from_this()); // give the observer a shared_ptr for us so we don't get deleted - observer->resourceUpdated(); // ask the observer to poll us immediently, we might already have data - return shared_from_this(); // allow chaining -} -Resource::Ptr Resource::applyTo(QObject *target, const char *property) -{ - // the cast to ResourceObserver* is required to ensure the right overload gets choosen, - // since QObjectResourceObserver also inherits from QObject - return applyTo(static_cast<ResourceObserver *>(new QObjectResourceObserver(target, property))); -} - -QVariant Resource::getResourceInternal(const int typeId) const -{ - // no result (yet), but a placeholder? delegate to the placeholder. - if (m_handler->result().isNull() && m_placeholder) - { - return m_placeholder->getResourceInternal(typeId); - } - const QVariant variant = m_handler->result(); - const auto typePair = qMakePair(int(variant.type()), typeId); - - // do we have an explicit transformer? use it. - if (m_transfomers.contains(typePair)) - { - return m_transfomers.value(typePair)(variant); - } - else - { - // we do not have an explicit transformer, so we just pass the QVariant, which will automatically - // transform some types for us (different numbers to each other etc.) - return variant; - } -} - -void Resource::reportResult() -{ - for (ResourceObserver *observer : m_observers) - { - observer->resourceUpdated(); - } -} -void Resource::reportFailure(const QString &reason) -{ - for (ResourceObserver *observer : m_observers) - { - observer->setFailure(reason); - } -} -void Resource::reportProgress(const int progress) -{ - for (ResourceObserver *observer : m_observers) - { - observer->setProgress(progress); - } -} - -void Resource::notifyObserverDeleted(ResourceObserver *observer) -{ - m_observers.removeAll(observer); -} - -QString Resource::storageIdentifier(const QString &id, Resource::Ptr placeholder) -{ - if (placeholder) - { - return id + '#' + storageIdentifier(placeholder->m_resource, placeholder->m_placeholder); - } - else - { - return id; - } -} diff --git a/api/logic/resources/Resource.h b/api/logic/resources/Resource.h deleted file mode 100644 index 63e97b88..00000000 --- a/api/logic/resources/Resource.h +++ /dev/null @@ -1,132 +0,0 @@ -#pragma once - -#include <QString> -#include <QMap> -#include <QVariant> -#include <functional> -#include <memory> - -#include "ResourceObserver.h" -#include "TypeMagic.h" - -#include "multimc_logic_export.h" - -class ResourceHandler; - -/** Frontend class for resources - * - * Usage: - * Resource::create("icon:noaccount")->applyTo(accountsAction); - * Resource::create("web:http://asdf.com/image.png")->applyTo(imageLbl)->placeholder(Resource::create("icon:loading")); - * - * Memory management: - * Resource caches ResourcePtrs using weak pointers, so while a resource is still existing - * when a new resource is created the resources will be the same (including the same handler). - * - * ResourceObservers keep a shared pointer to the resource, as does the Resource itself to it's - * placeholder (if present). This means a resource stays valid while it's still used ("applied to" etc.) - * by something. When nothing uses it anymore it gets deleted. - * - * @note Always pass resource around using Resource::Ptr! Copy and move constructors are disabled for a reason. - */ -class MULTIMC_LOGIC_EXPORT Resource : public std::enable_shared_from_this<Resource> -{ - // only allow creation from Resource::create and disallow passing around non-pointers - explicit Resource(const QString &resource); - Resource(const Resource &) = delete; - Resource(Resource &&) = delete; -public: - using Ptr = std::shared_ptr<Resource>; - - ~Resource(); - - /// The returned pointer needs to be stored until either Resource::applyTo or Resource::then is called, or it is passed as - /// a placeholder to Resource::create itself. - static Ptr create(const QString &resource, Ptr placeholder = nullptr); - - /// Use these functions to specify what should happen when e.g. the resource changes - Ptr applyTo(ResourceObserver *observer); - Ptr applyTo(QObject *target, const char *property = nullptr); - template<typename Func> - Ptr then(Func &&func) - { - // Arg will be the functions argument with references and cv-qualifiers (const, volatile) removed - using Arg = TypeMagic::CleanType<typename TypeMagic::Function<Func>::Argument>; - // Ret will be the functions return type - using Ret = typename TypeMagic::Function<Func>::ReturnType; - - // FunctionResourceObserver<ReturnType, ArgumentType, FunctionSignature> - return applyTo(new FunctionResourceObserver<Ret, Arg, Func>(std::forward<Func>(func))); - } - - /// Retrieve the currently active resource. If it's type is different from T a conversion will be attempted. - template<typename T> - T getResource() const { return getResourceInternal(qMetaTypeId<T>()).template value<T>(); } - - /// @internal Used by ResourceObserver and ResourceProxyModel - QVariant getResourceInternal(const int typeId) const; - - /** Register a new ResourceHandler. T needs to inherit from ResourceHandler - * Usage: Resource::registerHandler<MyResourceHandler>("myid"); - */ - template<typename T> - static void registerHandler(const QString &id) - { - m_handlers.insert(id, [](const QString &res) { return std::make_shared<T>(res); }); - } - /** Register a new resource transformer - * Resource transformers are functions that are responsible for converting between different types, - * for example converting from a QByteArray to a QPixmap. They are registered "externally" because not - * all types might be available in this library, for example gui types like QPixmap. - * - * Usage: Resource::registerTransformer([](const InputType &type) { return OutputType(type); }); - * This assumes that OutputType has a constructor that takes InputType as an argument. More - * complicated transformers can of course also be registered. - * - * When a ResourceObserver requests a type that's different from the actual resource type, a matching - * transformer will be looked up from the list of transformers. - * @note Only one-stage transforms will be performed (you can't registerTransformers for QString => int - * and int => float and expect QString to automatically be transformed into a float. - */ - template<typename Func> - static void registerTransformer(Func &&func) - { - using Out = typename TypeMagic::Function<Func>::ReturnType; - using In = TypeMagic::CleanType<typename TypeMagic::Function<Func>::Argument>; - static_assert(!std::is_same<Out, In>::value, "It does not make sense to transform a value to itself"); - m_transfomers.insert(qMakePair(qMetaTypeId<In>(), qMetaTypeId<Out>()), [func](const QVariant &in) - { - return QVariant::fromValue<Out>(func(in.value<In>())); - }); - } - -private: // half private, implementation details - friend class ResourceHandler; - // the following three functions are called by ResourceHandlers - /** Notifies the observers. They will call Resource::getResourceInternal which will call ResourceHandler::result - * or delegate to it's placeholder. - */ - void reportResult(); - void reportFailure(const QString &reason); - void reportProgress(const int progress); - - friend class ResourceObserver; - /// Removes observer from the list of observers so that we don't attempt to notify something that doesn't exist - void notifyObserverDeleted(ResourceObserver *observer); - -private: // truly private - QList<ResourceObserver *> m_observers; - std::shared_ptr<ResourceHandler> m_handler = nullptr; - Ptr m_placeholder = nullptr; - const QString m_resource; - - static QString storageIdentifier(const QString &id, Ptr placeholder = nullptr); - QString storageIdentifier() const; - - // a list of resource handler factories, registered using registerHandler - static QMap<QString, std::function<std::shared_ptr<ResourceHandler>(const QString &)>> m_handlers; - // a list of resource transformers, registered using registerTransformer - static QMap<QPair<int, int>, std::function<QVariant(QVariant)>> m_transfomers; - // a list of resources so that we can reuse them - static QMap<QString, std::weak_ptr<Resource>> m_resources; -}; diff --git a/api/logic/resources/ResourceHandler.cpp b/api/logic/resources/ResourceHandler.cpp deleted file mode 100644 index 46a4422c..00000000 --- a/api/logic/resources/ResourceHandler.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "ResourceHandler.h" - -#include "Resource.h" - -void ResourceHandler::setResult(const QVariant &result) -{ - m_result = result; - if (m_resource) - { - m_resource->reportResult(); - } -} - -void ResourceHandler::setFailure(const QString &reason) -{ - if (m_resource) - { - m_resource->reportFailure(reason); - } -} - -void ResourceHandler::setProgress(const int progress) -{ - if (m_resource) - { - m_resource->reportProgress(progress); - } -} diff --git a/api/logic/resources/ResourceHandler.h b/api/logic/resources/ResourceHandler.h deleted file mode 100644 index f09d8904..00000000 --- a/api/logic/resources/ResourceHandler.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include <QVariant> -#include <memory> - -#include "multimc_logic_export.h" - -class Resource; - -/** Base class for things that can retrieve a resource. - * - * Subclass, provide a constructor that takes a single QString as argument, and - * call Resource::registerHandler<MyResourceHandler>("<id>"), where <id> is the - * prefix of the resource ("web", "icon", etc.) - */ -class MULTIMC_LOGIC_EXPORT ResourceHandler -{ -public: - virtual ~ResourceHandler() {} - - void setResource(Resource *resource) { m_resource = resource; } - /// reimplement this if you need to do something after you have been put in a shared pointer - // we do this instead of inheriting from std::enable_shared_from_this - virtual void init(std::shared_ptr<ResourceHandler>&) {} - - QVariant result() const { return m_result; } - -protected: // use these methods to notify the resource of changes - void setResult(const QVariant &result); - void setFailure(const QString &reason); - void setProgress(const int progress); - -private: - QVariant m_result; - Resource *m_resource = nullptr; -}; diff --git a/api/logic/resources/ResourceObserver.cpp b/api/logic/resources/ResourceObserver.cpp deleted file mode 100644 index 4f168fd2..00000000 --- a/api/logic/resources/ResourceObserver.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "ResourceObserver.h" - -#include <QDebug> - -#include "Resource.h" - -static const char *defaultPropertyForTarget(QObject *target) -{ - if (target->inherits("QLabel")) - { - return "pixmap"; - } - else if (target->inherits("QAction") || - target->inherits("QMenu") || - target->inherits("QAbstractButton")) - { - return "icon"; - } - // for unit tests - else if (target->inherits("DummyObserverObject")) - { - return "property"; - } - else - { - Q_ASSERT_X(false, "ResourceObserver.cpp: defaultPropertyForTarget", "Unrecognized QObject subclass"); - return nullptr; - } -} - -QObjectResourceObserver::QObjectResourceObserver(QObject *target, const char *property) - : QObject(target), m_target(target) -{ - const QMetaObject *mo = m_target->metaObject(); - m_property = mo->property(mo->indexOfProperty( - property ? - property - : defaultPropertyForTarget(target))); -} -void QObjectResourceObserver::resourceUpdated() -{ - m_property.write(m_target, getInternal(m_property.type())); -} - - -ResourceObserver::~ResourceObserver() -{ - m_resource->notifyObserverDeleted(this); -} - -QVariant ResourceObserver::getInternal(const int typeId) const -{ - Q_ASSERT(m_resource); - return m_resource->getResourceInternal(typeId); -} diff --git a/api/logic/resources/ResourceObserver.h b/api/logic/resources/ResourceObserver.h deleted file mode 100644 index c42e41ba..00000000 --- a/api/logic/resources/ResourceObserver.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include <memory> -#include <functional> - -#include <QObject> -#include <QMetaProperty> -#include "multimc_logic_export.h" - -class QVariant; -class Resource; - -/// Base class for things that can use a resource -class MULTIMC_LOGIC_EXPORT ResourceObserver -{ -public: - virtual ~ResourceObserver(); - -protected: // these methods are called by the Resource when something changes - virtual void resourceUpdated() = 0; - virtual void setFailure(const QString &) {} - virtual void setProgress(const int) {} - -private: - friend class Resource; - void setSource(std::shared_ptr<Resource> resource) { m_resource = resource; } - -protected: - template<typename T> - T get() const { return getInternal(qMetaTypeId<T>()).template value<T>(); } - QVariant getInternal(const int typeId) const; - -private: - std::shared_ptr<Resource> m_resource; -}; - -/** Observer for QObject properties - * - * Give it a target and the name of a property, and that property will be set when the resource changes. - * - * If no name is given an attempt to find a default property for some common classes is done. - */ -class MULTIMC_LOGIC_EXPORT QObjectResourceObserver : public QObject, public ResourceObserver -{ -public: - explicit QObjectResourceObserver(QObject *target, const char *property = nullptr); - - void resourceUpdated() override; - -private: - QObject *m_target; - QMetaProperty m_property; -}; - -/** Observer for functions, lambdas etc. - * Template arguments: - * * We need Ret and Arg in order to create the std::function - * * We need Func in order to std::forward the function - */ -template <typename Ret, typename Arg, typename Func> -class FunctionResourceObserver : public ResourceObserver -{ - std::function<Ret(Arg)> m_function; -public: - template <typename T> - explicit FunctionResourceObserver(T &&func) - : m_function(std::forward<Func>(func)) {} - - void resourceUpdated() override - { - m_function(get<Arg>()); - } -}; diff --git a/api/logic/resources/ResourceProxyModel.cpp b/api/logic/resources/ResourceProxyModel.cpp deleted file mode 100644 index f026d9a9..00000000 --- a/api/logic/resources/ResourceProxyModel.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "ResourceProxyModel.h" - -#include <QItemSelectionRange> - -#include "Resource.h" -#include "ResourceObserver.h" - -class ModelResourceObserver : public ResourceObserver -{ -public: - explicit ModelResourceObserver(const QModelIndex &index, const int role) - : m_index(index), m_role(role) - { - qRegisterMetaType<QVector<int>>("QVector<int>"); - } - - void resourceUpdated() override - { - if (m_index.isValid()) - { - // the resource changed, pretend to be the model and notify the views of the update. they will re-poll the model which will return the new resource value - QMetaObject::invokeMethod(const_cast<QAbstractItemModel *>(m_index.model()), - "dataChanged", Qt::QueuedConnection, - Q_ARG(QModelIndex, m_index), Q_ARG(QModelIndex, m_index), Q_ARG(QVector<int>, QVector<int>() << m_role)); - } - } - -private: - QPersistentModelIndex m_index; - int m_role; -}; - -ResourceProxyModel::ResourceProxyModel(const int resultTypeId, QObject *parent) - : QIdentityProxyModel(parent), m_resultTypeId(resultTypeId) -{ -} - -QVariant ResourceProxyModel::data(const QModelIndex &proxyIndex, int role) const -{ - const QModelIndex mapped = mapToSource(proxyIndex); - // valid cell that's a Qt::DecorationRole and that contains a non-empty string - if (mapped.isValid() && role == Qt::DecorationRole && !mapToSource(proxyIndex).data(role).toString().isEmpty()) - { - // do we already have a resource for this index? - if (!m_resources.contains(mapped)) - { - Resource::Ptr placeholder; - const QVariant placeholderIdentifier = mapped.data(PlaceholderRole); - if (!placeholderIdentifier.isNull() && placeholderIdentifier.type() == QVariant::String) - { - placeholder = Resource::create(placeholderIdentifier.toString()); - } - - // create the Resource and apply the observer for models - Resource::Ptr res = Resource::create(mapToSource(proxyIndex).data(role).toString(), placeholder) - ->applyTo(new ModelResourceObserver(proxyIndex, role)); - - m_resources.insert(mapped, res); - } - - return m_resources.value(mapped)->getResourceInternal(m_resultTypeId); - } - // otherwise fall back to the source model - return mapped.data(role); -} - -void ResourceProxyModel::setSourceModel(QAbstractItemModel *model) -{ - if (sourceModel()) - { - disconnect(sourceModel(), 0, this, 0); - } - if (model) - { - connect(model, &QAbstractItemModel::dataChanged, this, [this](const QModelIndex &tl, const QModelIndex &br, const QVector<int> &roles) - { - // invalidate resources so that they will be re-created - if (roles.contains(Qt::DecorationRole) || roles.contains(PlaceholderRole) || roles.isEmpty()) - { - const QItemSelectionRange range(tl, br); - for (const QModelIndex &index : range.indexes()) - { - m_resources.remove(index); - } - } - }); - } - QIdentityProxyModel::setSourceModel(model); -} diff --git a/api/logic/resources/ResourceProxyModel.h b/api/logic/resources/ResourceProxyModel.h deleted file mode 100644 index 98a3dbd1..00000000 --- a/api/logic/resources/ResourceProxyModel.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include <QIdentityProxyModel> -#include <memory> - -#include "multimc_logic_export.h" - -/// Convenience proxy model that transforms resource identifiers (strings) for Qt::DecorationRole into other types. -class MULTIMC_LOGIC_EXPORT ResourceProxyModel : public QIdentityProxyModel -{ - Q_OBJECT -public: - // resultTypeId is found using qMetaTypeId<T>() - explicit ResourceProxyModel(const int resultTypeId, QObject *parent = nullptr); - - enum - { - // provide this role from your model if you want to show a placeholder - PlaceholderRole = Qt::UserRole + 0xabc // some random offset to not collide with other stuff - }; - - QVariant data(const QModelIndex &proxyIndex, int role) const override; - void setSourceModel(QAbstractItemModel *model) override; - - /// Helper function, usage: m_view->setModel(ResourceProxyModel::mixin<QIcon>(m_model)); - template <typename T> - static QAbstractItemModel *mixin(QAbstractItemModel *model) - { - ResourceProxyModel *proxy = new ResourceProxyModel(qMetaTypeId<T>(), model); - proxy->setSourceModel(model); - return proxy; - } - -private: - // mutable because it needs to be available from the const data() - mutable QMap<QPersistentModelIndex, std::shared_ptr<class Resource>> m_resources; - - const int m_resultTypeId; -}; |