From df86d80a85a6f4ac5867ffdc33eabca34a8a3bc9 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Fri, 23 Aug 2024 17:26:28 +0200 Subject: [PATCH] FEXQonfig: Clean up object ownership --- Source/Tools/FEXQonfig/Main.cpp | 102 +++++++++++++++----------------- Source/Tools/FEXQonfig/Main.h | 11 +++- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/Source/Tools/FEXQonfig/Main.cpp b/Source/Tools/FEXQonfig/Main.cpp index d2819a84f..033f8f690 100644 --- a/Source/Tools/FEXQonfig/Main.cpp +++ b/Source/Tools/FEXQonfig/Main.cpp @@ -184,10 +184,6 @@ static void ConfigInit(fextl::string ConfigFilename) { } } -QQuickWindow* Window = nullptr; // TODO: Drop global - -fextl::unique_ptr RootFSList; - RootFSModel::RootFSModel() { INotifyFD = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); @@ -245,6 +241,35 @@ QUrl RootFSModel::getBaseUrl() const { return QUrl::fromLocalFile(QString::fromStdString(FEXCore::Config::GetDataDirectory().c_str()) + "RootFS/"); } +void RootFSModel::INotifyThreadFunc() { + while (!ExitRequest.try_wait()) { + constexpr size_t DATA_SIZE = (16 * (sizeof(struct inotify_event) + NAME_MAX + 1)); + char buf[DATA_SIZE]; + int Ret {}; + do { + fd_set Set {}; + FD_ZERO(&Set); + FD_SET(INotifyFD, &Set); + struct timeval tv {}; + // 50 ms + tv.tv_usec = 50000; + Ret = select(INotifyFD + 1, &Set, nullptr, nullptr, &tv); + } while (Ret == 0 && INotifyFD != -1); + + if (Ret == -1 || INotifyFD == -1) { + // Just return on error + return; + } + + // Spin through the events, we don't actually care what they are + while (read(INotifyFD, buf, DATA_SIZE) > 0) + ; + + // Queue update to the data model + QMetaObject::invokeMethod(this, "Reload"); + } +} + // Returns true on success static bool OpenFile(fextl::string Filename) { std::error_code ec {}; @@ -281,42 +306,28 @@ static bool OpenFile(fextl::string Filename) { return true; } -fextl::unique_ptr ConfigModelInst; +ConfigRuntime::ConfigRuntime(const QString& ConfigFilename) { + qmlRegisterSingletonInstance("FEX.ConfigModel", 1, 0, "ConfigModel", &ConfigModelInst); + qmlRegisterSingletonInstance("FEX.RootFSModel", 1, 0, "RootFSModel", &RootFSList); + Engine.load(QUrl("qrc:/main.qml")); + + Window = qobject_cast(Engine.rootObjects().first()); + if (!ConfigFilename.isEmpty()) { + Window->setProperty("configFilename", QUrl::fromLocalFile(ConfigFilename)); + } else { + Window->setProperty("configDirty", true); + } + + ConfigRuntime::connect(Window, SIGNAL(selectedConfigFile(const QUrl&)), this, SLOT(onLoad(const QUrl&))); + ConfigRuntime::connect(Window, SIGNAL(triggeredSave(const QUrl&)), this, SLOT(onSave(const QUrl&))); + ConfigRuntime::connect(&ConfigModelInst, SIGNAL(modelReset()), Window, SLOT(refreshUI())); +} void ConfigRuntime::onSave(const QUrl& Filename) { qInfo() << "Saving to" << Filename.toLocalFile().toStdString().c_str(); FEX::Config::SaveLayerToJSON(Filename.toLocalFile().toStdString().c_str(), LoadedConfig.get()); } -void RootFSModel::INotifyThreadFunc() { - while (!ExitRequest.try_wait()) { - constexpr size_t DATA_SIZE = (16 * (sizeof(struct inotify_event) + NAME_MAX + 1)); - char buf[DATA_SIZE]; - int Ret {}; - do { - fd_set Set {}; - FD_ZERO(&Set); - FD_SET(INotifyFD, &Set); - struct timeval tv {}; - // 50 ms - tv.tv_usec = 50000; - Ret = select(INotifyFD + 1, &Set, nullptr, nullptr, &tv); - } while (Ret == 0 && INotifyFD != -1); - - if (Ret == -1 || INotifyFD == -1) { - // Just return on error - return; - } - - // Spin through the events, we don't actually care what they are - while (read(INotifyFD, buf, DATA_SIZE) > 0) - ; - - // Queue update to the data model - QMetaObject::invokeMethod(RootFSList.get(), "Reload"); - } -} - void ConfigRuntime::onLoad(const QUrl& Filename) { // TODO: Distinguish between "load" and "overlay". // Currently, the new configuration is overlaid on top of the previous one. @@ -331,8 +342,8 @@ void ConfigRuntime::onLoad(const QUrl& Filename) { return; } - ConfigModelInst->Reload(); - RootFSList->Reload(); + ConfigModelInst.Reload(); + RootFSList.Reload(); QMetaObject::invokeMethod(Window, "refreshUI"); } @@ -351,24 +362,7 @@ int main(int Argc, char** Argv) { LoadDefaultSettings(); } - ConfigRuntime Runtime; - - ConfigModelInst = fextl::make_unique(); - RootFSList = fextl::make_unique(); - - QQmlApplicationEngine Engine; - qmlRegisterSingletonInstance("FEX.ConfigModel", 1, 0, "ConfigModel", ConfigModelInst.get()); - qmlRegisterSingletonInstance("FEX.RootFSModel", 1, 0, "RootFSModel", RootFSList.get()); - Engine.load(QUrl("qrc:/main.qml")); - /*auto**/ Window = qobject_cast(Engine.rootObjects().first()); - if (!ConfigFilename.empty()) { - Window->setProperty("configFilename", "file://" + QString {ConfigFilename.c_str()}); - } else { - Window->setProperty("configDirty", true); - } - ConfigRuntime::connect(Window, SIGNAL(selectedConfigFile(const QUrl&)), &Runtime, SLOT(onLoad(const QUrl&))); - ConfigRuntime::connect(Window, SIGNAL(triggeredSave(const QUrl&)), &Runtime, SLOT(onSave(const QUrl&))); - ConfigRuntime::connect(ConfigModelInst.get(), SIGNAL(modelReset()), Window, SLOT(refreshUI())); + ConfigRuntime Runtime(ConfigFilename.c_str()); return App.exec(); } diff --git a/Source/Tools/FEXQonfig/Main.h b/Source/Tools/FEXQonfig/Main.h index bd674e783..3f22571ab 100644 --- a/Source/Tools/FEXQonfig/Main.h +++ b/Source/Tools/FEXQonfig/Main.h @@ -1,9 +1,11 @@ #include -#include +#include #include #include +class QQuickWindow; + class ConfigModel : public QStandardItemModel { Q_OBJECT QML_ELEMENT @@ -59,8 +61,13 @@ public slots: class ConfigRuntime : public QObject { Q_OBJECT + QQmlApplicationEngine Engine; + QQuickWindow* Window = nullptr; + RootFSModel RootFSList; + ConfigModel ConfigModelInst; + public: - ConfigRuntime() {} + ConfigRuntime(const QString& ConfigFilename); public slots: void onSave(const QUrl&);