diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index 0835e3b1f..49326c83d 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -47,6 +47,7 @@ class Mod : public Resource Q_OBJECT public: using Ptr = shared_qobject_ptr; + using WeakPtr = QPointer; Mod() = default; Mod(const QFileInfo &file); diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index c316e710c..8bdab16e2 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -226,9 +226,9 @@ bool ModFolderModel::stopWatching() return ResourceFolderModel::stopWatching({ m_dir.absolutePath(), indexDir().absolutePath() }); } -auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> QList +auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> QList { - QList selected_resources; + QList selected_resources; for (auto i : indexes) { if(i.column() != 0) continue; @@ -238,12 +238,13 @@ auto ModFolderModel::selectedMods(QModelIndexList& indexes) -> QList return selected_resources; } -auto ModFolderModel::allMods() -> QList +auto ModFolderModel::allMods() -> QList { - QList mods; + QList mods; - for (auto res : m_resources) + for (auto& res : m_resources) { mods.append(static_cast(res.get())); + } return mods; } diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index b1f307108..7fe830c24 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -101,8 +101,8 @@ public: QDir indexDir() { return { QString("%1/.index").arg(dir().absolutePath()) }; } - auto selectedMods(QModelIndexList& indexes) -> QList; - auto allMods() -> QList; + auto selectedMods(QModelIndexList& indexes) -> QList; + auto allMods() -> QList; RESOURCE_HELPERS(Mod) diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index bec7490f2..e76bc49ef 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "QObjectPtr.h" @@ -31,6 +32,7 @@ class Resource : public QObject { Q_DISABLE_COPY(Resource) public: using Ptr = shared_qobject_ptr; + using WeakPtr = QPointer; Resource(QObject* parent = nullptr); Resource(QFileInfo file_info); diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 982915e2f..c27a5e2d0 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -135,7 +135,7 @@ bool ResourceFolderModel::installResource(QString original_path) bool ResourceFolderModel::uninstallResource(QString file_name) { - for (auto resource : m_resources) { + for (auto& resource : m_resources) { if (resource->fileinfo().fileName() == file_name) return resource->destroy(); } @@ -155,7 +155,7 @@ bool ResourceFolderModel::deleteResources(const QModelIndexList& indexes) continue; } - auto resource = m_resources.at(i.row()); + auto& resource = m_resources.at(i.row()); resource->destroy(); } return true; @@ -183,7 +183,7 @@ bool ResourceFolderModel::update() return true; } -void ResourceFolderModel::resolveResource(Resource::Ptr res) +void ResourceFolderModel::resolveResource(Resource::WeakPtr res) { if (!res->shouldResolve()) { return; diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 986d98856..59d2388a4 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -15,10 +15,10 @@ class QSortFilterProxyModel; /** A basic model for external resources. * - * To implement one such model, you need to implement, at the very minimum: - * - columnCount: The number of columns in your model. - * - data: How the model data is displayed and accessed. - * - headerData: Display properties of the header. + * This model manages a list of resources. As such, external users of such resources do not own them, + * and the resource's lifetime is contingent on the model's lifetime. + * + * TODO: Make the resources unique pointers accessible through weak pointers. */ class ResourceFolderModel : public QAbstractListModel { Q_OBJECT @@ -62,7 +62,7 @@ class ResourceFolderModel : public QAbstractListModel { virtual bool update(); /** Creates a new parse task, if needed, for 'res' and start it.*/ - virtual void resolveResource(Resource::Ptr res); + virtual void resolveResource(Resource::WeakPtr res); [[nodiscard]] size_t size() const { return m_resources.size(); }; [[nodiscard]] bool empty() const { return size() == 0; } @@ -151,7 +151,7 @@ class ResourceFolderModel : public QAbstractListModel { * * This usually calls static_cast on the specific Task type returned by createUpdateTask, * so care must be taken in such cases. - * TODO: Figure out a way to express this relationship better without templated classes (Q_OBJECT macro dissalows that). + * TODO: Figure out a way to express this relationship better without templated classes (Q_OBJECT macro disallows that). */ virtual void onUpdateSucceeded(); virtual void onUpdateFailed() {} @@ -189,33 +189,34 @@ class ResourceFolderModel : public QAbstractListModel { }; /* A macro to define useful functions to handle Resource* -> T* more easily on derived classes */ -#define RESOURCE_HELPERS(T) \ - [[nodiscard]] T* operator[](size_t index) \ - { \ - return static_cast(m_resources[index].get()); \ - } \ - [[nodiscard]] T* at(size_t index) \ - { \ - return static_cast(m_resources[index].get()); \ - } \ - [[nodiscard]] const T* at(size_t index) const \ - { \ - return static_cast(m_resources.at(index).get()); \ - } \ - [[nodiscard]] T* first() \ - { \ - return static_cast(m_resources.first().get()); \ - } \ - [[nodiscard]] T* last() \ - { \ - return static_cast(m_resources.last().get()); \ - } \ - [[nodiscard]] T* find(QString id) \ - { \ - auto iter = std::find_if(m_resources.begin(), m_resources.end(), [&](Resource::Ptr r) { return r->internal_id() == id; }); \ - if (iter == m_resources.end()) \ - return nullptr; \ - return static_cast((*iter).get()); \ +#define RESOURCE_HELPERS(T) \ + [[nodiscard]] T* operator[](size_t index) \ + { \ + return static_cast(m_resources[index].get()); \ + } \ + [[nodiscard]] T* at(size_t index) \ + { \ + return static_cast(m_resources[index].get()); \ + } \ + [[nodiscard]] const T* at(size_t index) const \ + { \ + return static_cast(m_resources.at(index).get()); \ + } \ + [[nodiscard]] T* first() \ + { \ + return static_cast(m_resources.first().get()); \ + } \ + [[nodiscard]] T* last() \ + { \ + return static_cast(m_resources.last().get()); \ + } \ + [[nodiscard]] T* find(QString id) \ + { \ + auto iter = std::find_if(m_resources.constBegin(), m_resources.constEnd(), \ + [&](Resource::Ptr const& r) { return r->internal_id() == id; }); \ + if (iter == m_resources.constEnd()) \ + return nullptr; \ + return static_cast((*iter).get()); \ } /* Template definition to avoid some code duplication */ @@ -231,7 +232,7 @@ void ResourceFolderModel::applyUpdates(QSet& current_set, QSet auto row = m_resources_index[kept]; auto new_resource = new_resources[kept]; - auto current_resource = m_resources[row]; + auto const& current_resource = m_resources[row]; if (new_resource->dateTimeChanged() == current_resource->dateTimeChanged()) { // no significant change, ignore... @@ -301,7 +302,7 @@ void ResourceFolderModel::applyUpdates(QSet& current_set, QSet { m_resources_index.clear(); int idx = 0; - for (auto mod : m_resources) { + for (auto const& mod : m_resources) { m_resources_index[mod->internal_id()] = idx; idx++; } diff --git a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h index 0fd5c292c..2944c7479 100644 --- a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h @@ -17,7 +17,7 @@ class BasicFolderLoadTask : public Task Q_OBJECT public: struct Result { - QMap resources; + QMap resources; }; using ResultPtr = std::shared_ptr; diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index e8180c115..44cb1d5fd 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -52,7 +52,7 @@ void ModFolderLoadTask::executeTask() // Read JAR files that don't have metadata m_mods_dir.refresh(); for (auto entry : m_mods_dir.entryInfoList()) { - Mod::Ptr mod(new Mod(entry)); + Mod* mod(new Mod(entry)); if (mod->enabled()) { if (m_result->mods.contains(mod->internal_id())) { diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index d73c8ebb6..a91f6e5ce 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -36,7 +36,7 @@ static ModAPI::ModLoaderTypes mcLoaders(BaseInstance* inst) ModUpdateDialog::ModUpdateDialog(QWidget* parent, BaseInstance* instance, const std::shared_ptr mods, - QList& search_for) + QList& search_for) : ReviewMessageBox(parent, tr("Confirm mods to update"), "") , m_parent(parent) , m_mod_model(mods) @@ -226,9 +226,8 @@ auto ModUpdateDialog::ensureMetadata() -> bool }; for (auto candidate : m_candidates) { - auto* candidate_ptr = candidate.get(); if (candidate->status() != ModStatus::NoMetadata) { - onMetadataEnsured(candidate_ptr); + onMetadataEnsured(candidate); continue; } @@ -236,7 +235,7 @@ auto ModUpdateDialog::ensureMetadata() -> bool continue; if (confirm_rest) { - addToTmp(candidate_ptr, provider_rest); + addToTmp(candidate, provider_rest); should_try_others.insert(candidate->internal_id(), try_others_rest); continue; } @@ -261,7 +260,7 @@ auto ModUpdateDialog::ensureMetadata() -> bool should_try_others.insert(candidate->internal_id(), response.try_others); if (confirmed) - addToTmp(candidate_ptr, response.chosen); + addToTmp(candidate, response.chosen); } if (!modrinth_tmp.empty()) { diff --git a/launcher/ui/dialogs/ModUpdateDialog.h b/launcher/ui/dialogs/ModUpdateDialog.h index 76aaab36a..bd486f0da 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.h +++ b/launcher/ui/dialogs/ModUpdateDialog.h @@ -19,7 +19,7 @@ class ModUpdateDialog final : public ReviewMessageBox { explicit ModUpdateDialog(QWidget* parent, BaseInstance* instance, const std::shared_ptr mod_model, - QList& search_for); + QList& search_for); void checkCandidates(); @@ -46,7 +46,7 @@ class ModUpdateDialog final : public ReviewMessageBox { const std::shared_ptr m_mod_model; - QList& m_candidates; + QList& m_candidates; QList m_modrinth_to_update; QList m_flame_to_update;