Sun, 08 Sep 2013 16:14:58 +0300
Use the cfg:: namespace system I made up a while ago instead of using QSettings directly, it's unsafe
src/cfg.cpp | file | annotate | diff | comparison | revisions | |
src/cfg.h | file | annotate | diff | comparison | revisions | |
src/config.cpp | file | annotate | diff | comparison | revisions | |
src/config.h | file | annotate | diff | comparison | revisions | |
src/demo.cpp | file | annotate | diff | comparison | revisions | |
src/demo.h | file | annotate | diff | comparison | revisions | |
src/main.cpp | file | annotate | diff | comparison | revisions | |
src/main.h | file | annotate | diff | comparison | revisions | |
src/misc.cpp | file | annotate | diff | comparison | revisions | |
src/misc.h | file | annotate | diff | comparison | revisions | |
src/prompts.cpp | file | annotate | diff | comparison | revisions | |
src/prompts.h | file | annotate | diff | comparison | revisions | |
src/src.pro | file | annotate | diff | comparison | revisions | |
src/types.h | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cfg.cpp Sun Sep 08 16:14:58 2013 +0300 @@ -0,0 +1,153 @@ +/* + * ZanDemo: Zandronum demo launcher + * Copyright (C) 2013 Santeri Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <cassert> +#include <QDir> +#include <QTextStream> +#include <QSettings> +#include "main.h" +#include "config.h" + +#define MAX_CONFIG 512 + +// ============================================================================= +// ----------------------------------------------------------------------------- +namespace cfg { + static struct { + void* ptr; + Type type; + const char* name; + QVariant def; + } g_configData[MAX_CONFIG]; + + static int g_cfgDataCursor = 0; + +#define CASE(T) case T##Type: return QVariant (*(reinterpret_cast<T*> (ptr))); + static QVariant getConfigValue (void* ptr, Type type) { + switch (type) { + CASE (Int) + CASE (String) + CASE (Float) + CASE (Bool) + CASE (List) + CASE (Map) + + case KeySeqType: + return QVariant (reinterpret_cast<KeySeq*> (ptr)->toString()); + } + + assert (false); + return QVariant(); + } +#undef CASE + +#define CASE(T, METHOD) case T##Type: (*(reinterpret_cast<T*> (ptr))) = val.METHOD(); return; + static void setConfigValue (void* ptr, Type type, const QVariant& val) { + switch (type) { + CASE (Int, toInt) + CASE (String, toString) + CASE (Float, toFloat) + CASE (Bool, toBool) + CASE (List, toList) + CASE (Map, toMap) + + case KeySeqType: + reinterpret_cast<KeySeq*> (ptr)->fromString (val.toString()); + break; + } + } + + // ============================================================================= + // Get the QSettings object. + // ----------------------------------------------------------------------------- + static QSettings* getSettingsObject() { + return new QSettings; + } + + // ============================================================================= + // Load the configuration from file + // ----------------------------------------------------------------------------- + bool load() { + QSettings* settings = getSettingsObject(); + print ("config::load: Loading configuration file from %1\n", settings->fileName()); + + for (alias i : g_configData) { + if (i.name == null) + break; + + setConfigValue (i.ptr, i.type, settings->value (i.name, i.def)); + } + + settings->deleteLater(); + return true; + } + + // ============================================================================= + // Save the configuration to disk + // ----------------------------------------------------------------------------- + bool save() { + QSettings* settings = getSettingsObject(); + settings->clear(); + print ("Saving configuration to %1...\n", settings->fileName()); + + for (alias i : g_configData) { + if (i.name == null) + break; + + QVariant val = getConfigValue (i.ptr, i.type); + + if (val == i.def) + continue; + + settings->setValue (i.name, val); + } + + settings->sync(); + settings->deleteLater(); + return true; + } + + // ============================================================================= + // Reset configuration defaults. + // ----------------------------------------------------------------------------- + void reset() { + for (alias i : g_configData) { + if (i.name == null) + break; + + setConfigValue (i.ptr, i.type, i.def); + } + } + + // ============================================================================= + // We cannot just add config objects to a list or vector because that would rely + // on the vector's c-tor being called before the configs' c-tors. With global + // variables we cannot assume that!! Therefore we need to use a C-style array here. + // ----------------------------------------------------------------------------- + ConfigAdder::ConfigAdder (void* ptr, Type type, const char* name, QVariant def) { + if (g_cfgDataCursor == 0) + memset (g_configData, 0, sizeof g_configData); + + assert (g_cfgDataCursor < MAX_CONFIG); + alias i = g_configData[g_cfgDataCursor++]; + i.ptr = ptr; + i.type = type; + i.name = name; + i.def = def; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cfg.h Sun Sep 08 16:14:58 2013 +0300 @@ -0,0 +1,64 @@ +/* + * ZanDemo: Zandronum demo launcher + * Copyright (C) 2013 Santeri Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ZANDEMO_CFG_H +#define ZANDEMO_CFG_H + +// ============================================================================= +#include <QString> +#include <QVariant> +#include <QKeySequence> + +#define CONFIG(T, NAME, DEFAULT) namespace cfg { T NAME = DEFAULT; } \ + cfg::ConfigAdder zz_ConfigAdder_##NAME (&cfg::NAME, cfg::T##Type, #NAME, DEFAULT); + +#define EXTERN_CONFIG(T, NAME) namespace cfg { extern T NAME; } + +// ========================================================= +namespace cfg { + enum Type { + IntType, + StringType, + FloatType, + BoolType, + KeySeqType, + ListType, + MapType, + }; + + // Type-definitions for the above enum list + typedef int Int; + typedef QString String; + typedef float Float; + typedef bool Bool; + typedef QKeySequence KeySeq; + typedef QList<QVariant> List; + typedef QMap<QString, QVariant> Map; + + // ------------------------------------------ + bool load(); + bool save(); + void reset(); + + class ConfigAdder { + public: + ConfigAdder (void* ptr, Type type, const char* name, QVariant def); + }; +}; + +#endif // ZANDEMO_CFG_H \ No newline at end of file
--- a/src/config.cpp Sun Aug 11 16:08:13 2013 +0300 +++ b/src/config.cpp Sun Sep 08 16:14:58 2013 +0300 @@ -27,6 +27,12 @@ #include "demo.h" #include "build/moc_config.cpp" +CONFIG (Bool, noprompt, false) +CONFIG (List, devBuildNames, cfg::List()) +CONFIG (List, releaseNames, cfg::List()) +CONFIG (List, wadpaths, cfg::List()) +CONFIG (Map, binaryPaths, cfg::Map()) + // ============================================================================= // ----------------------------------------------------------------------------- class FindPathButton : public QPushButton { @@ -48,8 +54,10 @@ // ============================================================================= // ----------------------------------------------------------------------------- -ConfigBox::ConfigBox (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) { - ui = new Ui_ConfigBox; +ConfigBox::ConfigBox (QWidget* parent, Qt::WindowFlags f) : + QDialog (parent, f), + ui (new Ui_ConfigBox) +{ ui->setupUi (this); initVersions(); @@ -60,7 +68,7 @@ connect (ui->wad_findPath, SIGNAL (clicked()), this, SLOT (findPath())); connect (ui->wad_del, SIGNAL (clicked()), this, SLOT (delPath())); connect (ui->buttonBox, SIGNAL (clicked (QAbstractButton*)), this, - SLOT (buttonPressed (QAbstractButton*))); + SLOT (buttonPressed (QAbstractButton*))); setWindowTitle (fmt (APPNAME " %1", versionString())); } @@ -73,77 +81,70 @@ // ============================================================================= // ----------------------------------------------------------------------------- void ConfigBox::initVersions() { - QFormLayout* releaseLayout = new QFormLayout (ui->zandronumVersions), - *testLayout = new QFormLayout (ui->betaVersions); - list<var> versions = getVersionsList(), - releases = getReleasesList(); + m_releaseLayout = new QFormLayout (ui->zandronumVersions); + m_testLayout = new QFormLayout (ui->betaVersions); + + for (const var& ver : cfg::devBuildNames) + addVersion (ver.toString(), false); - for (const var& ver : versions) { - str verstring = ver.toString(); - - bool isRelease = false; - for (const var& rel : releases) { - if (rel.toString() == verstring) { - isRelease = true; - break; - } - } - - QLabel* lb = new QLabel (verstring + ":"); - QLineEdit* ledit = new QLineEdit; - FindPathButton* btn = new FindPathButton; - btn->setEditWidget (ledit); + for (const var& rel : cfg::releaseNames) + addVersion (rel.toString(), true); +} - QWidget* wdg = new QWidget; - QHBoxLayout* leditLayout = new QHBoxLayout (wdg); - leditLayout->addWidget (ledit); - leditLayout->addWidget (btn); - - m_zanBinaries << ledit; - connect (btn, SIGNAL (clicked()), this, SLOT (findZanBinary())); - - if (isRelease) - releaseLayout->addRow (lb, wdg); - else - testLayout->addRow (lb, wdg); - } +// ============================================================================= +// ----------------------------------------------------------------------------- +void ConfigBox::addVersion (const str& name, bool isRelease) { + QLabel* lb = new QLabel (name + ":"); + QLineEdit* ledit = new QLineEdit; + FindPathButton* btn = new FindPathButton; + btn->setEditWidget (ledit); + + QWidget* wdg = new QWidget; + QHBoxLayout* leditLayout = new QHBoxLayout (wdg); + leditLayout->addWidget (ledit); + leditLayout->addWidget (btn); + + m_zanBinaries << ledit; + connect (btn, SIGNAL (clicked()), this, SLOT (findZanBinary())); + + if (isRelease) + m_releaseLayout->addRow (lb, wdg); + else + m_testLayout->addRow (lb, wdg); } // ============================================================================= // ----------------------------------------------------------------------------- void ConfigBox::initFromSettings() { - QSettings cfg; ui->wad_pathsList->clear(); - list<var> paths = cfg.value ("wads/paths", list<var>()).toList(); - for (const var & it : paths) + for (const var& it : cfg::wadpaths) addPath (it.toString()); int i = 0; - list<var> versions = getVersionsList(); - for (const var& ver : versions) - m_zanBinaries[i++]->setText (cfg.value (binaryConfigName (ver.toString()), "").toString()); + for (const var& ver : getVersions()) + m_zanBinaries[i++]->setText (cfg::binaryPaths[ver.toString()].toString()); - ui->noDemoPrompt->setChecked (cfg.value ("nodemoprompt", false).toBool()); + ui->noDemoPrompt->setChecked (cfg::noprompt); } // ============================================================================= // ----------------------------------------------------------------------------- void ConfigBox::saveSettings() { - QSettings cfg; - list<var> wadPathList; + QList<QVariant> wadPathList; for (int i = 0; i < ui->wad_pathsList->count(); ++i) wadPathList << ui->wad_pathsList->item (i)->text(); - cfg.setValue ("wads/paths", wadPathList); - cfg.setValue ("nodemoprompt", ui->noDemoPrompt->isChecked()); + cfg::wadpaths = wadPathList; + cfg::noprompt = ui->noDemoPrompt->isChecked(); int i = 0; - list<var> versions = getVersionsList(); - for (const var& ver : versions) - cfg.setValue (binaryConfigName (ver.toString()), m_zanBinaries[i++]->text()); + for (const var& ver : getVersions()) + cfg::binaryPaths[ver.toString()] = m_zanBinaries[i++]->text(); + + cfg::save(); } // =============================================================================
--- a/src/config.h Sun Aug 11 16:08:13 2013 +0300 +++ b/src/config.h Sun Sep 08 16:14:58 2013 +0300 @@ -1,6 +1,3 @@ -#ifndef CONFIG_H -#define CONFIG_H - /* * ZanDemo: Zandronum demo launcher * Copyright (C) 2013 Santeri Piippo @@ -19,10 +16,14 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef ZANDEMO_CONFIG_H +#define ZANDEMO_CONFIG_H + #include <QDialog> #include "main.h" #include "types.h" +class QFormLayout; class QNetworkReply; class QHBoxLayout; class QLabel; @@ -35,9 +36,9 @@ Q_OBJECT public: - explicit ConfigBox( QWidget* parent = null, Qt::WindowFlags f = 0 ); + explicit ConfigBox (QWidget* parent = null, Qt::WindowFlags f = 0); virtual ~ConfigBox(); - void addPath( str path ); + void addPath (str path); void initFromSettings(); void saveSettings(); void initVersions(); @@ -49,11 +50,15 @@ void findPath(); void delPath(); void findZanBinary(); - void buttonPressed( QAbstractButton* btn ); + void buttonPressed (QAbstractButton* btn); private: - Ui_ConfigBox* ui; - list<QLineEdit*> m_zanBinaries; + Ui_ConfigBox* ui; + list<QLineEdit*> m_zanBinaries; + QFormLayout* m_releaseLayout, + * m_testLayout; + + void addVersion (const str& name, bool isRelease); }; -#endif // CONFIG_H \ No newline at end of file +#endif // ZANDEMO_CONFIG_H \ No newline at end of file
--- a/src/demo.cpp Sun Aug 11 16:08:13 2013 +0300 +++ b/src/demo.cpp Sun Sep 08 16:14:58 2013 +0300 @@ -25,6 +25,10 @@ #include "ui_demoprompt.h" #include "prompts.h" +EXTERN_CONFIG (Map, binaryPaths) +EXTERN_CONFIG (List, wadpaths) +EXTERN_CONFIG (Bool, noprompt) + static const uint32 g_demoSignature = makeByteID ('Z', 'C', 'L', 'D'); // ============================================================================= @@ -37,7 +41,7 @@ if (skip-- > 0) continue; - if (c.toLatin1() == '\034') { + if (c == QChar ('\034')) { skip = 1; continue; } @@ -63,10 +67,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- static bool isKnownVersion (str ver) { - QSettings cfg; - list<var> versions = getVersionsList(); - - for (const var& it : versions) + for (const var& it : getVersions()) if (it.toString() == ver || it.toString() + 'M' == ver) return true; @@ -76,10 +77,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- static str findWAD (str name) { - QSettings cfg; - list<var> paths = cfg.value ("wads/paths", list<var>()).toList(); - - if (paths.size() == 0) { + if (cfg::wadpaths.size() == 0) { error (tr ("No WAD paths configured!")); // Cannot just return an empty string here since that'd trigger @@ -87,7 +85,7 @@ exit (9); } - for (const var& it : paths) { + for (const var& it : cfg::wadpaths) { str fullpath = fmt ("%1/%2", it.toString(), name); QFile f (fullpath); @@ -231,8 +229,7 @@ } } - QSettings cfg; - str binarypath = cfg.value (binaryConfigName (zanversion)).toString(); + str binarypath = cfg::binaryPaths [zanversion].toString(); if (binarypath.isEmpty()) { error (fmt (tr ("No binary path specified for Zandronum version %1!"), zanversion)); @@ -261,7 +258,7 @@ pwadpaths << path; } - if (!cfg.value ("nodemoprompt", false).toBool()) { + if (!cfg::noprompt) { str pwadtext; for (const str& pwad : wads) { @@ -288,7 +285,7 @@ return 1; } - QStringList cmdlineList ( { + QStringList cmdlineList ({ "-playdemo", path, "-iwad", iwadpath, });
--- a/src/demo.h Sun Aug 11 16:08:13 2013 +0300 +++ b/src/demo.h Sun Sep 08 16:14:58 2013 +0300 @@ -16,8 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DEMO_H -#define DEMO_H +#ifndef ZANDEMO_DEMO_H +#define ZANDEMO_DEMO_H #include "types.h" @@ -43,4 +43,4 @@ int launchDemo (str path); -#endif // DEMO_H \ No newline at end of file +#endif // ZANDEMO_DEMO_H \ No newline at end of file
--- a/src/main.cpp Sun Aug 11 16:08:13 2013 +0300 +++ b/src/main.cpp Sun Sep 08 16:14:58 2013 +0300 @@ -17,9 +17,8 @@ */ #include <QApplication> -#include <QSettings> +#include "config.h" #include "types.h" -#include "config.h" #include "demo.h" // ============================================================================= @@ -30,6 +29,8 @@ app.setOrganizationName (UNIXNAME); app.setApplicationVersion (versionString()); + cfg::load(); + for (int i = 1; i < argc; ++i) { str arg = argv[i];
--- a/src/main.h Sun Aug 11 16:08:13 2013 +0300 +++ b/src/main.h Sun Sep 08 16:14:58 2013 +0300 @@ -16,8 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef MAIN_H -#define MAIN_H +#ifndef ZANDEMO_MAIN_H +#define ZANDEMO_MAIN_H #define APPNAME "ZanDemo" #define UNIXNAME "zandemo" @@ -33,13 +33,15 @@ #define BUILD_RC 3 #define BUILD_RELEASE 4 -#define elif else if +#define elif(A) else if (A) +#define alias auto& #include <QSettings> +#include "cfg.h" struct VersionInfo; static const std::nullptr_t null = nullptr; QString versionString(); -#endif // MAIN_H \ No newline at end of file +#endif // ZANDEMO_MAIN_H \ No newline at end of file
--- a/src/misc.cpp Sun Aug 11 16:08:13 2013 +0300 +++ b/src/misc.cpp Sun Sep 08 16:14:58 2013 +0300 @@ -18,46 +18,37 @@ #include "misc.h" +EXTERN_CONFIG (List, devBuildNames) +EXTERN_CONFIG (List, releaseNames) +EXTERN_CONFIG (Map, binaryPaths) + uint32 makeByteID (uint8 a, uint8 b, uint8 c, uint8 d) { return a | (b << 8) | (c << 16) | (d << 24); } // ============================================================================= // ----------------------------------------------------------------------------- +QList<QVariant> getVersions() { + return cfg::devBuildNames + cfg::releaseNames; +} + +// ============================================================================= +// ----------------------------------------------------------------------------- str binaryConfigName (str ver) { return fmt ("binaries/%1", ver); } // ============================================================================= // ----------------------------------------------------------------------------- -list<var> getVersionsList() { - QSettings cfg; - return cfg.value ("binarynames", list<var>()).toList(); -} - -// ============================================================================= -// ----------------------------------------------------------------------------- -list<var> getReleasesList() { - QSettings cfg; - return cfg.value ("releasenames", list<var>()).toList(); -} - -// ============================================================================= -// ----------------------------------------------------------------------------- void addVersion (str name, bool isRelease, str binaryPath) { - QSettings cfg; - list<var> versions = getVersionsList(); - versions << var (name); - cfg.setValue ("binarynames", versions); - cfg.setValue (binaryConfigName (name), binaryPath); + cfg::binaryPaths[name] = binaryPath; - if (isRelease) { - versions = getReleasesList(); - versions << var (name); - cfg.setValue ("releasenames", versions); - } + if (isRelease) + cfg::releaseNames << var (name); + else + cfg::devBuildNames << var (name); - cfg.sync(); + cfg::save(); } // ============================================================================= @@ -69,4 +60,4 @@ return path.mid (lastpos + 1); return path; -} +} \ No newline at end of file
--- a/src/misc.h Sun Aug 11 16:08:13 2013 +0300 +++ b/src/misc.h Sun Sep 08 16:14:58 2013 +0300 @@ -16,18 +16,18 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef MISC_H -#define MISC_H +#ifndef ZANDEMO_MISC_H +#define ZANDEMO_MISC_H #include "types.h" uint32 makeByteID (uint8 a, uint8 b, uint8 c, uint8 d); str binaryConfigName (str ver); str basename (str path); -list<var> getVersionsList(); -list<var> getReleasesList(); void addVersion (str name, bool isRelease, str binaryPath); +QList<QVariant> getVersions(); + // ----------------------------------------------------------------------------- // Templated clamp template<class T> static inline T clamp (T a, T min, T max) { @@ -49,4 +49,4 @@ return (a >= 0) ? a : -a; } -#endif // MISC_H \ No newline at end of file +#endif // ZANDEMO_MISC_H \ No newline at end of file
--- a/src/prompts.cpp Sun Aug 11 16:08:13 2013 +0300 +++ b/src/prompts.cpp Sun Sep 08 16:14:58 2013 +0300 @@ -19,8 +19,8 @@ #include "prompts.h" #include "ui_unknownversion.h" #include "misc.h" +#include "config.h" #include "build/moc_prompts.cpp" -#include "config.h" // ============================================================================= // -----------------------------------------------------------------------------
--- a/src/prompts.h Sun Aug 11 16:08:13 2013 +0300 +++ b/src/prompts.h Sun Sep 08 16:14:58 2013 +0300 @@ -16,8 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef PROMPTS_H -#define PROMPTS_H +#ifndef ZANDEMO_PROMPTS_H +#define ZANDEMO_PROMPTS_H #include <QDialog> #include "main.h" @@ -44,4 +44,4 @@ bool m_isRelease; }; -#endif // PROMPTS_H \ No newline at end of file +#endif // ZANDEMO_PROMPTS_H \ No newline at end of file
--- a/src/src.pro Sun Aug 11 16:08:13 2013 +0300 +++ b/src/src.pro Sun Sep 08 16:14:58 2013 +0300 @@ -1,3 +1,4 @@ +CONFIG += qt debug TARGET = ../zandemo DEPENDPATH += . INCLUDEPATH += .
--- a/src/types.h Sun Aug 11 16:08:13 2013 +0300 +++ b/src/types.h Sun Sep 08 16:14:58 2013 +0300 @@ -16,8 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef TYPES_H -#define TYPES_H +#ifndef ZANDEMO_TYPES_H +#define ZANDEMO_TYPES_H #include "main.h" #include <QString> @@ -128,4 +128,4 @@ void fprint (FILE* fp, const char* fmtstr, ...); #endif -#endif // TYPES_H \ No newline at end of file +#endif // ZANDEMO_TYPES_H \ No newline at end of file