Simplified configuration code. Use a std::vector object to contain config pointers and have config objects register themselves upon creation instead of relying on a cfgdefs.h. Removed sections, all configurations are just simply written one after another now.

Mon, 25 Mar 2013 16:05:03 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Mon, 25 Mar 2013 16:05:03 +0200
changeset 69
6790dea720a8
parent 68
c637b172d565
child 70
e6b8dab8f81a

Simplified configuration code. Use a std::vector object to contain config pointers and have config objects register themselves upon creation instead of relying on a cfgdefs.h. Removed sections, all configurations are just simply written one after another now.

cfgdef.h file | annotate | diff | comparison | revisions
config.cpp file | annotate | diff | comparison | revisions
config.h file | annotate | diff | comparison | revisions
file.cpp file | annotate | diff | comparison | revisions
gldraw.cpp file | annotate | diff | comparison | revisions
gui.cpp file | annotate | diff | comparison | revisions
ldforge.pro file | annotate | diff | comparison | revisions
ldtypes.cpp file | annotate | diff | comparison | revisions
zz_configDialog.cpp file | annotate | diff | comparison | revisions
--- a/cfgdef.h	Mon Mar 25 15:20:56 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- *  LDForge: LDraw parts authoring CAD
- *  Copyright (C) 2013 Santeri `arezey` 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/>.
- */
-
-// SECT (prefix, Display name)
-// CFG (type, prefix, name, description, default)
-
-// ---------------------------------------------------------
-SECT (io, Files)
-CFG (str, io, ldpath, "LDraw path", "")
-
-SECT (gl, GLRenderer)
-CFG (str, gl, bgcolor, "Background color", "#CCCCD9")
-CFG (str, gl, maincolor, "Main color", "#707078")
-CFG (float, gl, maincolor_alpha, "Main color translucency [0.0 - 1.0]", 1.0)
-CFG (int, gl, linethickness, "Line thickness", 2)
-CFG (bool, gl, colorbfc, "Green-red BFC view", true)
-
-SECT (lv, ListView)
-CFG (bool, lv, colorize, "Show colorized polygons in their color in the list view", true)
\ No newline at end of file
--- a/config.cpp	Mon Mar 25 15:20:56 2013 +0200
+++ b/config.cpp	Mon Mar 25 16:05:03 2013 +0200
@@ -17,53 +17,14 @@
  */
 
 #include <stdio.h>
-// #include <stdlib.h>
+#include <stdlib.h>
 #include <errno.h>
 #include <time.h>
 #include "str.h"
 #include "config.h"
-
-#ifdef CONFIG_WITH_QT
 #include <QDir>
-#endif // CONFIG_WITH_QT
-
-// =============================================================================
-// Define the configs
-#define CFG(TYPE, SECT, NAME, DESCR, DEFAULT) \
-	TYPE##config SECT##_##NAME (CFGSECTNAME (SECT), DESCR, \
-		DEFAULT, #NAME, #SECT "_" #NAME, #TYPE, #DEFAULT);
-
-#define SECT(...)
- #include "cfgdef.h"
-#undef CFG
-#undef SECT
 
-// =============================================================================
-config* config::pointers[] = {
-#define CFG(TYPE, SECT, NAME, DESCR, DEFAULT) &SECT##_##NAME,
-#define SECT(...)
- #include "cfgdef.h"
-#undef CFG
-#undef SECT
-};
-
-// =============================================================================
-const char* config::sections[] = {
-#define CFG(...)
-#define SECT(A,B) #A,
- #include "cfgdef.h"
-#undef CFG
-#undef SECT
-};
-
-// =============================================================================
-const char* config::sectionNames[] = {
-#define CFG(...)
-#define SECT(A,B) #B,
- #include "cfgdef.h"
-#undef CFG
-#undef SECT
-};
+std::vector<config*> g_pConfigPointers;
 
 // =============================================================================
 const char* g_WeekdayNames[7] = {
@@ -110,7 +71,6 @@
 	char linedata[MAX_INI_LINE];
 	char* line;
 	size_t ln = 0;
-	configsection_e section = NO_CONFIG_SECTION;
 	
 	if (!fp)
 		return false; // can't open for reading
@@ -126,32 +86,6 @@
 		if (*line == '\0' || line[0] == '#')
 			continue; // Empty line or comment.
 		
-		if (line[0] == '[') {
-			// Section
-			char* endbracket = strchr (line, ']');
-			
-			if (!endbracket) {
-				fprintf (stderr, "badly formed section: %s", line);
-				continue;
-			}
-			
-			str sectionName = str (line).substr (1, endbracket - line);
-			const configsection_e oldsection = section;
-			section = NO_CONFIG_SECTION;
-			
-			// Find the section
-			for (unsigned i = 0; i < NUM_ConfigSections && section == NO_CONFIG_SECTION; i++)
-				if (sectionName.compare (sectionNames[i]) == 0)
-					section = (configsection_e)i;
-			
-			if (section == NO_CONFIG_SECTION) {
-				fprintf (stderr, "unknown config section `%s`\n", sectionName.chars());
-				section = oldsection;
-			}
-			
-			continue;
-		}
-		
 		// Find the equals sign.
 		char* equals = strchr (line, '=');
 		if (!equals) {
@@ -161,17 +95,14 @@
 		
 		str entry = str (line).substr (0, equals - line);
 		
-		str configname;
-		configname.format ("%s_%s", sections[section], entry.chars ());
-		
 		// Find the config entry for this.
-		config* cfg = NULL;
-		for (size_t i = 0; i < NUM_CONFIG && !cfg; i++)
-			if (configname.compare (pointers[i]->fullname) == 0)
-				cfg = pointers[i];
+		config* cfg = nullptr;
+		for (config* i : g_pConfigPointers)
+			if (entry == i->name)
+				cfg = i;
 		
 		if (!cfg) {
-			fprintf (stderr, "unknown config `%s`\n", configname.chars());
+			fprintf (stderr, "unknown config `%s`\n", entry.chars());
 			continue;
 		}
 		
@@ -237,21 +168,14 @@
 	// are written properly.
 	setlocale (LC_NUMERIC, "C");
 	
-#ifdef APPNAME
-	#ifdef CONFIG_WITH_QT
-		// If the directory doesn't exist, create it now.
-		if (!QDir (dirpath().chars()).exists ()) {
-			fprintf (stderr, "Creating config path %s...\n", dirpath().chars());
-			if (!QDir ().mkpath (dirpath().chars())) {
-				fprintf (stderr, "Failed to create the directory. Configuration cannot be saved!\n");
-				return false; // Couldn't create directory
-			}
+	// If the directory doesn't exist, create it now.
+	if (!QDir (dirpath().chars()).exists ()) {
+		fprintf (stderr, "Creating config path %s...\n", dirpath().chars());
+		if (!QDir ().mkpath (dirpath().chars())) {
+			fprintf (stderr, "Failed to create the directory. Configuration cannot be saved!\n");
+			return false; // Couldn't create directory
 		}
-	#else
-		#warning Need QT to check for directories. Config will not be able
-		#warning to save properly if ~/.APPNAME/ does not exist.
-	#endif // CONFIG_WITH_QT
-#endif // CONFIG_DIRECTORY
+	}
 	
 	FILE* fp = fopen (filepath().chars(), "w");
 	printf ("writing cfg to %s\n", filepath().chars());
@@ -273,59 +197,40 @@
 		g_WeekdayNames[timeinfo->tm_wday], g_MonthNames[timeinfo->tm_mon],
 		timeinfo->tm_mday, daysuffix, timeinfo->tm_year + 1900,
 		timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
-	writef (fp, "\n");
 	
-	for (int i = 0; i < NUM_ConfigSections; i++) {
-		if (i > 0)
-			writef (fp, "\n");
-		
-		writef (fp, "[%s]\n", sectionNames[i]);
-		bool first = true;
-		
-		for (size_t j = 0; j < NUM_CONFIG; j++) {
-			config* cfg = pointers[j];
-			
-			if (cfg->sect != i)
-				continue;
-			
-			if (!first)
-				writef (fp, "\n");
+	for (config* cfg : g_pConfigPointers) {
+		str valstring;
+		switch (cfg->getType()) {
+		case CONFIG_int:
+			valstring.format ("%d", static_cast<intconfig*> (cfg)->value);
+			break;
+		case CONFIG_str:
+			valstring = static_cast<strconfig*> (cfg)->value;
+			break;
+		case CONFIG_float:
+			valstring.format ("%f", static_cast<floatconfig*> (cfg)->value);
 			
-			str valstring;
-			switch (cfg->getType()) {
-			case CONFIG_int:
-				valstring.format ("%d", static_cast<intconfig*> (cfg)->value);
-				break;
-			case CONFIG_str:
-				valstring = static_cast<strconfig*> (cfg)->value;
-				break;
-			case CONFIG_float:
-				valstring.format ("%f", static_cast<floatconfig*> (cfg)->value);
+			// Trim any trailing zeros
+			if (valstring.first (".") != -1) {
+				while (valstring[~valstring - 1] == '0')
+					valstring -= 1;
 				
-				// Trim any trailing zeros
-				if (valstring.first (".") != -1) {
-					while (valstring[~valstring - 1] == '0')
-						valstring -= 1;
-					
-					// But don't trim the only one out...
-					if (valstring[~valstring - 1] == '.')
-						valstring += '0';
-				}
-				
-				break;
-			case CONFIG_bool:
-				valstring = (static_cast<boolconfig*> (cfg)->value) ? "true" : "false";
-				break;
-			default:
-				break;
+				// But don't trim the only one out...
+				if (valstring[~valstring - 1] == '.')
+					valstring += '0';
 			}
 			
-			// Write the entry now.
-			writef (fp, "# %s, default: %s\n", g_ConfigTypeNames[cfg->getType()], cfg->defaultstring);
-			writef (fp, "# %s: %s\n", cfg->fullname, cfg->description);
-			writef (fp, "%s=%s\n", cfg->name, valstring.chars());
-			first = false;
+			break;
+		case CONFIG_bool:
+			valstring = (static_cast<boolconfig*> (cfg)->value) ? "true" : "false";
+			break;
+		default:
+			break;
 		}
+		
+		// Write the entry now.
+		writef (fp, "\n# [%s] default: %s\n", g_ConfigTypeNames[cfg->getType()], cfg->defaultstring);
+		writef (fp, "%s=%s\n", cfg->name, valstring.chars());
 	}
 	
 	fclose (fp);
@@ -335,35 +240,20 @@
 // =============================================================================
 void config::reset () {
 	for (size_t i = 0; i < NUM_CONFIG; i++)
-		pointers[i]->resetValue ();
+		g_pConfigPointers[i]->resetValue ();
 }
 
 // =============================================================================
 str config::filepath () {
-#ifdef APPNAME
 	str path;
-	path.format ("%s" APPNAME ".ini", dirpath().chars());
+	path.format ("%s" CONFIGFILE, dirpath().chars());
 	return path;
-#else // APPNAME
-	return "config.ini";
-#endif // APPNAME
 }
 
 // =============================================================================
 str config::dirpath () {
-#ifdef APPNAME
-	str path;
-	
-	#ifdef CONFIG_WITH_QT
-		path = (QDir::homePath ().toStdString().c_str());
-	#else // CONFIG_WITH_QT
-		path = "~";
-	#endif // CONFIG_WITH_QT
-	
+	str path = (QDir::homePath ().toStdString().c_str());
 	path += "/." APPNAME "/";
-#else
-	path = "./";
-#endif // APPNAME
 	
 	return path;
 }
\ No newline at end of file
--- a/config.h	Mon Mar 25 15:20:56 2013 +0200
+++ b/config.h	Mon Mar 25 16:05:03 2013 +0200
@@ -23,34 +23,17 @@
 #include "str.h"
 
 // =============================================================================
-// Determine configuration file. Use APPNAME if given.
-#ifdef APPNAME
- #define CONFIGFILE APPNAME ".ini"
-#else // APPNAME
- #define APPNAME "(unnamed application)"
- #define CONFIGFILE "config.ini"
-#endif // APPNAME
-
-#ifdef CONFIG_WITH_QT
- #include <QString>
-#endif // CONFIG_WITH_QT
-
-// -------------------------------
-#define CFGSECTNAME(X) CFGSECT_##X
+#define CONFIGFILE APPNAME ".cfg"
+#include <QString>
 
 #define MAX_INI_LINE 512
-#define NUM_CONFIG (sizeof config::pointers / sizeof *config::pointers)
+#define NUM_CONFIG (g_pConfigPointers.size ())
 
-// =============================================================================
-enum configsection_e {
-#define CFG(...)
-#define SECT(A,B) CFGSECTNAME (A),
- #include "cfgdef.h"
-#undef CFG
-#undef SECT
-	NUM_ConfigSections,
-	NO_CONFIG_SECTION = -1
-};
+#define cfg(T, NAME, DEFAULT) \
+	T##config NAME (DEFAULT, #NAME, #T, #DEFAULT)
+
+#define extern_cfg(T, NAME) \
+	extern T##config NAME
 
 // =============================================================================
 enum configtype_e {
@@ -64,8 +47,7 @@
 // =========================================================
 class config {
 public:
-	configsection_e sect;
-	const char* description, *name, *fullname, *typestring, *defaultstring;
+	const char* name, *typestring, *defaultstring;
 	
 	virtual configtype_e getType () {
 		return CONFIG_none;
@@ -77,13 +59,12 @@
 	static bool load ();
 	static bool save ();
 	static void reset ();
-	static config* pointers[];
-	static const char* sections[];
-	static const char* sectionNames[];
 	static str dirpath ();
 	static str filepath ();
 };
 
+extern std::vector<config*> g_pConfigPointers;
+
 // =============================================================================
 #define DEFINE_UNARY_OPERATOR(T, OP) \
 	T operator OP () { \
@@ -130,17 +111,14 @@
 #define IMPLEMENT_CONFIG(T) \
 	T value, defval; \
 	\
-	T##config (const configsection_e _sect, const char* _description, \
-		T _defval, const char* _name, const char* _fullname, const char* _typestring, \
+	T##config (T _defval, const char* _name, const char* _typestring, \
 		const char* _defaultstring) \
 	{ \
-		sect = _sect; \
-		description = _description; \
 		value = defval = _defval; \
 		name = _name; \
-		fullname = _fullname; \
 		typestring = _typestring; \
 		defaultstring = _defaultstring; \
+		g_pConfigPointers.push_back (this); \
 	} \
 	operator T () { \
 		return value; \
@@ -148,7 +126,7 @@
 	configtype_e getType () { \
 		return CONFIG_##T; \
 	} \
-	void resetValue () { \
+	virtual void resetValue () { \
 		value = defval; \
 	}
 
@@ -235,12 +213,4 @@
 	DEFINE_ASSIGN_OPERATOR (bool, =)
 };
 
-// =============================================================================
-// Extern the configurations now
-#define CFG(TYPE, SECT, NAME, DESCR, DEFAULT) extern TYPE##config SECT##_##NAME;
-#define SECT(...)
- #include "cfgdef.h"
-#undef CFG
-#undef SECT
-
 #endif // __OPTIONS_H__
\ No newline at end of file
--- a/file.cpp	Mon Mar 25 15:20:56 2013 +0200
+++ b/file.cpp	Mon Mar 25 16:05:03 2013 +0200
@@ -19,11 +19,14 @@
 #include <vector>
 
 #include "common.h"
+#include "config.h"
 #include "file.h"
 #include "misc.h"
 #include "bbox.h"
 #include "gui.h"
 
+cfg (str, io_ldpath, "");
+
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
--- a/gldraw.cpp	Mon Mar 25 15:20:56 2013 +0200
+++ b/gldraw.cpp	Mon Mar 25 16:05:03 2013 +0200
@@ -20,6 +20,7 @@
 #include <QGLWidget>
 #include <GL/glu.h>
 #include "common.h"
+#include "config.h"
 #include "file.h"
 #include "gldraw.h"
 #include "bbox.h"
@@ -28,6 +29,12 @@
 static double g_faObjectOffset[3];
 static double g_StoredBBoxSize;
 
+cfg (str, gl_bgcolor, "#CCCCD9");
+cfg (str, gl_maincolor, "#707078");
+cfg (float, gl_maincolor_alpha, 1.0);
+cfg (int, gl_linethickness, 2);
+cfg (bool, gl_colorbfc, true);
+
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
--- a/gui.cpp	Mon Mar 25 15:20:56 2013 +0200
+++ b/gui.cpp	Mon Mar 25 16:05:03 2013 +0200
@@ -22,7 +22,7 @@
 #include "gldraw.h"
 #include "gui.h"
 #include "file.h"
-
+#include "config.h"
 #include "zz_setContentsDialog.h"
 #include "zz_configDialog.h"
 #include "zz_addObjectDialog.h"
@@ -37,6 +37,8 @@
 
 vector<LDObject*> g_Clipboard;
 
+cfg (bool, lv_colorize, true);
+
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
--- a/ldforge.pro	Mon Mar 25 15:20:56 2013 +0200
+++ b/ldforge.pro	Mon Mar 25 16:05:03 2013 +0200
@@ -19,7 +19,6 @@
 	misc.h \
 	str.h \
 	config.h \
-	cfgdef.h \
 	colors.h \
 	types.h \
 	zz_setContentsDialog.h \
--- a/ldtypes.cpp	Mon Mar 25 15:20:56 2013 +0200
+++ b/ldtypes.cpp	Mon Mar 25 16:05:03 2013 +0200
@@ -298,13 +298,13 @@
 	
 	// If we have this cached, just clone that
 	if (bDeepInline && pFile->objCache.size ()) {
-		FOREACH (LDObject, *, obj, pFile->objCache)
+		for (LDObject* obj : pFile->objCache)
 			objs.push_back (obj->makeClone ());
 	} else {
 		if (!bDeepInline)
 			bCache = false;
 		
-		FOREACH (LDObject, *, obj, pFile->objects) {
+		for (LDObject* obj : pFile->objects) {
 			// Skip those without schemantic meaning
 			switch (obj->getType ()) {
 			case OBJ_Comment:
@@ -325,7 +325,7 @@
 				
 				vector<LDObject*> otherobjs = ref->inlineContents (true, false);
 				
-				FOREACH (LDObject, *, otherobj, otherobjs) {
+				for (LDObject* otherobj : otherobjs) {
 					// Cache this object if desired
 					if (bCache)
 						cache.push_back (otherobj->makeClone ());
@@ -346,7 +346,7 @@
 	}
 	
 	// Transform the objects
-	FOREACH (LDObject, *, obj, objs)
+	for (LDObject* obj : objs)
 		transformObject (obj, mMatrix, vPosition, dColor);
 	
 	return objs;
--- a/zz_configDialog.cpp	Mon Mar 25 15:20:56 2013 +0200
+++ b/zz_configDialog.cpp	Mon Mar 25 16:05:03 2013 +0200
@@ -19,10 +19,19 @@
 #include "common.h"
 #include "zz_configDialog.h"
 #include "file.h"
+#include "config.h"
 #include <qgridlayout.h>
 #include <qfiledialog.h>
 #include <qcolordialog.h>
 
+extern_cfg (str, io_ldpath);
+extern_cfg (str, gl_bgcolor);
+extern_cfg (str, gl_maincolor);
+extern_cfg (bool, lv_colorize);
+extern_cfg (bool, gl_colorbfc);
+extern_cfg (float, gl_maincolor_alpha);
+extern_cfg (int, gl_linethickness);
+
 ConfigDialog* g_ConfigDialog = nullptr;
 
 #define INIT_CHECKBOX(BOX, CFG) \

mercurial