jni/src/util/string.cpp \
jni/src/util/timetaker.cpp \
jni/src/touchscreengui.cpp \
- jni/src/database-leveldb.cpp
+ jni/src/database-leveldb.cpp \
+ jni/src/settings.cpp
# lua api
LOCAL_SRC_FILES += \
add_subdirectory(util)
set(common_SRCS
- version.cpp
- rollback_interface.cpp
- rollback.cpp
- genericobject.cpp
- voxelalgorithms.cpp
- sound.cpp
- quicktune.cpp
- subgame.cpp
- inventorymanager.cpp
- mods.cpp
+ ban.cpp
+ base64.cpp
+ biome.cpp
+ cavegen.cpp
+ clientiface.cpp
+ collision.cpp
+ connection.cpp
content_abm.cpp
+ content_mapnode.cpp
+ content_nodemeta.cpp
+ content_sao.cpp
+ convert_json.cpp
craftdef.cpp
- nameidmapping.cpp
+ database-dummy.cpp
+ database-leveldb.cpp
+ database-redis.cpp
+ database-sqlite3.cpp
+ database.cpp
+ debug.cpp
+ defaultsettings.cpp
+ dungeongen.cpp
+ emerge.cpp
+ environment.cpp
+ filesys.cpp
+ genericobject.cpp
+ gettext.cpp
+ httpfetch.cpp
+ inventory.cpp
+ inventorymanager.cpp
itemdef.cpp
- nodedef.cpp
- object_properties.cpp
+ light.cpp
log.cpp
- content_sao.cpp
- emerge.cpp
+ map.cpp
+ mapblock.cpp
mapgen.cpp
+ mapgen_singlenode.cpp
mapgen_v6.cpp
mapgen_v7.cpp
- mapgen_singlenode.cpp
- treegen.cpp
- dungeongen.cpp
- cavegen.cpp
- content_nodemeta.cpp
- content_mapnode.cpp
- collision.cpp
+ mapnode.cpp
+ mapsector.cpp
+ mods.cpp
+ nameidmapping.cpp
+ nodedef.cpp
nodemetadata.cpp
nodetimer.cpp
- serverobject.cpp
noise.cpp
+ object_properties.cpp
+ pathfinder.cpp
+ player.cpp
porting.cpp
- tool.cpp
- defaultsettings.cpp
- mapnode.cpp
- voxel.cpp
- inventory.cpp
- debug.cpp
+ quicktune.cpp
+ rollback.cpp
+ rollback_interface.cpp
serialization.cpp
- light.cpp
- filesys.cpp
- connection.cpp
- environment.cpp
server.cpp
- clientiface.cpp
- socket.cpp
- mapblock.cpp
- mapsector.cpp
- map.cpp
- database.cpp
- database-dummy.cpp
- database-leveldb.cpp
- database-sqlite3.cpp
- database-redis.cpp
- player.cpp
- test.cpp
+ serverlist.cpp
+ serverobject.cpp
+ settings.cpp
sha1.cpp
- base64.cpp
- ban.cpp
- biome.cpp
+ socket.cpp
+ sound.cpp
staticobject.cpp
- serverlist.cpp
- pathfinder.cpp
- convert_json.cpp
- gettext.cpp
- httpfetch.cpp
+ subgame.cpp
+ test.cpp
+ tool.cpp
+ treegen.cpp
+ version.cpp
+ voxel.cpp
+ voxelalgorithms.cpp
${JTHREAD_SRCS}
${common_SCRIPT_SRCS}
${UTIL_SRCS}
set(minetest_SRCS
${common_SRCS}
${sound_SRCS}
- localplayer.cpp
- sky.cpp
- clientmap.cpp
- content_cso.cpp
- content_mapblock.cpp
- content_cao.cpp
- mesh.cpp
- mapblock_mesh.cpp
- keycode.cpp
camera.cpp
- clouds.cpp
- particles.cpp
- clientobject.cpp
chat.cpp
- hud.cpp
- guiKeyChangeMenu.cpp
- guiFormSpecMenu.cpp
- guiTable.cpp
- guiPasswordChange.cpp
- guiVolumeChange.cpp
- guiChatConsole.cpp
client.cpp
+ clientmap.cpp
clientmedia.cpp
+ clientobject.cpp
+ clouds.cpp
+ content_cao.cpp
+ content_cso.cpp
+ content_mapblock.cpp
+ convert_json.cpp
+ drawscene.cpp
filecache.cpp
- tile.cpp
- shader.cpp
game.cpp
- main.cpp
+ guiChatConsole.cpp
guiEngine.cpp
guiFileSelectMenu.cpp
- convert_json.cpp
- drawscene.cpp
+ guiFormSpecMenu.cpp
+ guiKeyChangeMenu.cpp
+ guiPasswordChange.cpp
+ guiTable.cpp
+ guiVolumeChange.cpp
+ hud.cpp
+ keycode.cpp
+ localplayer.cpp
+ main.cpp
+ mapblock_mesh.cpp
+ mesh.cpp
+ particles.cpp
+ shader.cpp
+ sky.cpp
+ tile.cpp
${minetest_SCRIPT_SRCS}
)
list(SORT minetest_SRCS)
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "client.h"
#include <iostream>
#include <algorithm>
-#include "clientserver.h"
+#include <sstream>
+#include <IFileSystem.h>
#include "jthread/jmutexautolock.h"
+#include "util/directiontables.h"
+#include "util/pointedthing.h"
+#include "util/serialize.h"
+#include "util/string.h"
+#include "strfnd.h"
+#include "client.h"
+#include "clientserver.h"
#include "main.h"
-#include <sstream>
#include "filesys.h"
#include "porting.h"
#include "mapsector.h"
#include "nodedef.h"
#include "itemdef.h"
#include "shader.h"
-#include <IFileSystem.h>
#include "base64.h"
#include "clientmap.h"
#include "clientmedia.h"
#include "sound.h"
-#include "util/string.h"
#include "IMeshCache.h"
#include "serialization.h"
-#include "util/serialize.h"
#include "config.h"
-#include "util/directiontables.h"
-#include "util/pointedthing.h"
#include "version.h"
#include "drawscene.h"
#include <sstream>
#include "clientiface.h"
+#include "util/numeric.h"
+#include "util/mathconstants.h"
#include "player.h"
#include "settings.h"
#include "mapblock.h"
#include "map.h"
#include "emerge.h"
#include "serverobject.h" // TODO this is used for cleanup of only
-
-#include "util/numeric.h"
-#include "util/mathconstants.h"
-
#include "main.h" // for g_settings
+#include "log.h"
const char *ClientInterface::statenames[] = {
"Invalid",
*/
#include "clientmedia.h"
+#include "util/serialize.h"
+#include "util/string.h"
#include "httpfetch.h"
#include "client.h"
#include "clientserver.h"
#include "filecache.h"
+#include "filesys.h"
#include "hex.h"
#include "sha1.h"
#include "debug.h"
#include "porting.h"
#include "settings.h"
#include "main.h"
-#include "util/serialize.h"
-#include "util/string.h"
static std::string getMediaCacheDir()
{
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include <ICameraSceneNode.h>
+#include <ITextSceneNode.h>
+#include <IBillboardSceneNode.h>
+#include <IMeshManipulator.h>
+#include <IAnimatedMeshSceneNode.h>
+#include <IBoneSceneNode.h>
#include "content_cao.h"
+#include "util/numeric.h" // For IntervalLimiter
+#include "util/serialize.h"
+#include "util/mathconstants.h"
#include "tile.h"
#include "environment.h"
#include "collision.h"
#include "settings.h"
-#include <ICameraSceneNode.h>
-#include <ITextSceneNode.h>
-#include <IBillboardSceneNode.h>
#include "serialization.h" // For decompressZlib
#include "gamedef.h"
#include "clientobject.h"
#include "sound.h"
#include "nodedef.h"
#include "localplayer.h"
-#include "util/numeric.h" // For IntervalLimiter
-#include "util/serialize.h"
-#include "util/mathconstants.h"
#include "map.h"
#include "main.h" // g_settings
#include "camera.h" // CameraModes
-#include <IMeshManipulator.h>
-#include <IAnimatedMeshSceneNode.h>
-#include <IBoneSceneNode.h>
+#include "log.h"
class Settings;
struct ToolCapabilities;
*/
#include "content_mapblock.h"
-
+#include "util/numeric.h"
+#include "util/directiontables.h"
#include "main.h" // For g_settings
#include "mapblock_mesh.h" // For MapBlock_LightColor() and MeshCollector
#include "settings.h"
#include "nodedef.h"
#include "tile.h"
#include "gamedef.h"
-#include "util/numeric.h"
-#include "util/directiontables.h"
+#include "log.h"
+
// Create a cuboid.
// collector - the MeshCollector for the resulting polygons
*/
#include "content_sao.h"
+#include "util/serialize.h"
+#include "util/mathconstants.h"
#include "collision.h"
#include "environment.h"
#include "settings.h"
#include "player.h"
#include "scripting_game.h"
#include "genericobject.h"
-#include "util/serialize.h"
-#include "util/mathconstants.h"
+#include "log.h"
std::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
#include "config.h"
#if USE_LEVELDB
-/*
-LevelDB databases
-*/
-
#include "database-leveldb.h"
#include "leveldb/db.h"
#include "main.h"
#include "settings.h"
#include "log.h"
+#include "filesys.h"
#define ENSURE_STATUS_OK(s) \
if (!(s).ok()) { \
#include "main.h"
#include "settings.h"
#include "log.h"
+#include "filesys.h"
Database_SQLite3::Database_SQLite3(ServerMap *map, std::string savedir)
{
// if unspecified, leave a proc for the main thread and one for
// some other misc thread
- int nthreads = 0;
+ s16 nthreads = 0;
if (!g_settings->getS16NoEx("num_emerge_threads", nthreads))
nthreads = porting::getNumberOfProcessors() - 2;
if (nthreads < 1)
if (qlimit_generate < 1)
qlimit_generate = 1;
- for (int i = 0; i != nthreads; i++)
- emergethread.push_back(new EmergeThread((Server *)gamedef, i));
+ for (s16 i = 0; i < nthreads; i++)
+ emergethread.push_back(new EmergeThread((Server *) gamedef, i));
infostream << "EmergeManager: using " << nthreads << " threads" << std::endl;
}
// Open file and deserialize
std::ifstream is(path.c_str(), std::ios_base::binary);
- if(is.good() == false)
- {
- infostream<<"ServerEnvironment::loadMeta(): Failed to open "
- <<path<<std::endl;
+ if (!is.good()) {
+ infostream << "ServerEnvironment::loadMeta(): Failed to open "
+ << path << std::endl;
throw SerializationError("Couldn't load env meta");
}
Settings args;
-
- for(;;)
- {
- if(is.eof())
- throw SerializationError
- ("ServerEnvironment::loadMeta(): EnvArgsEnd not found");
- std::string line;
- std::getline(is, line);
- std::string trimmedline = trim(line);
- if(trimmedline == "EnvArgsEnd")
- break;
- args.parseConfigLine(line);
+
+ if (!args.parseConfigLines(is, "EnvArgsEnd")) {
+ throw SerializationError("ServerEnvironment::loadMeta(): "
+ "EnvArgsEnd not found!");
}
-
- try{
+
+ try {
m_game_time = args.getU64("game_time");
- }catch(SettingNotFoundException &e){
+ } catch (SettingNotFoundException &e) {
// Getting this is crucial, otherwise timestamps are useless
throw SerializationError("Couldn't load env meta game_time");
}
- try{
+ try {
m_time_of_day = args.getU64("time_of_day");
- }catch(SettingNotFoundException &e){
+ } catch (SettingNotFoundException &e) {
// This is not as important
m_time_of_day = 9000;
}
#include "guiEngine.h"
+#include <IGUIStaticText.h>
+#include <ICameraSceneNode.h>
#include "scripting_mainmenu.h"
+#include "util/numeric.h"
#include "config.h"
#include "version.h"
#include "porting.h"
#include "sound_openal.h"
#include "clouds.h"
#include "httpfetch.h"
-#include "util/numeric.h"
+#include "log.h"
#ifdef __ANDROID__
#include "tile.h"
#include <GLES/gl.h>
#endif
-#include <IGUIStaticText.h>
-#include <ICameraSceneNode.h>
/******************************************************************************/
/** TextDestGuiEngine */
#include "settings.h"
#include "craftdef.h"
#include "rollback_interface.h"
+#include "strfnd.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
#include "settings.h"
#include "log.h"
#include "hex.h"
+#include "debug.h"
class UnknownKeycode : public BaseException
{
{
DSTACK(__FUNCTION_NAME);
- /*infostream<<"ServerMap::loadMapMeta(): Loading map metadata"
- <<std::endl;*/
-
- std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";
+ std::string fullpath = m_savedir + DIR_DELIM "map_meta.txt";
std::ifstream is(fullpath.c_str(), std::ios_base::binary);
- if(is.good() == false)
- {
- infostream<<"ERROR: ServerMap::loadMapMeta(): "
- <<"could not open"<<fullpath<<std::endl;
+ if (!is.good()) {
+ errorstream << "ServerMap::loadMapMeta(): "
+ << "could not open" << fullpath << std::endl;
throw FileNotGoodException("Cannot open map metadata");
}
Settings params;
- for(;;)
- {
- if(is.eof())
- throw SerializationError
- ("ServerMap::loadMapMeta(): [end_of_params] not found");
- std::string line;
- std::getline(is, line);
- std::string trimmedline = trim(line);
- if(trimmedline == "[end_of_params]")
- break;
- params.parseConfigLine(line);
+ if (!params.parseConfigLines(is, "[end_of_params]")) {
+ throw SerializationError("ServerMap::loadMapMeta(): "
+ "[end_of_params] not found!");
}
m_emerge->loadParamsFromSettings(¶ms);
- verbosestream<<"ServerMap::loadMapMeta(): seed="
- << m_emerge->params.seed<<std::endl;
+ verbosestream << "ServerMap::loadMapMeta(): seed="
+ << m_emerge->params.seed << std::endl;
}
void ServerMap::saveSectorMeta(ServerMapSector *sector)
#include "mapblock.h"
#include "mapnode.h"
#include "map.h"
-//#include "serverobject.h"
#include "content_sao.h"
#include "nodedef.h"
#include "content_mapnode.h" // For content_mapnode_get_new_name
#include "serialization.h"
#include "util/serialize.h"
#include "filesys.h"
+#include "log.h"
FlagDesc flagdesc_mapgen[] = {
struct MapgenParams {
std::string mg_name;
- int chunksize;
+ s16 chunksize;
u64 seed;
- int water_level;
+ s16 water_level;
u32 flags;
MapgenSpecificParams *sparams;
#include "nameidmapping.h"
#include "util/numeric.h"
#include "util/serialize.h"
-//#include "profiler.h" // For TimeTaker
+#include "exceptions.h"
+#include "debug.h"
/*
NodeBox
*/
#include "player.h"
+
+#include <fstream>
+#include "util/numeric.h"
#include "hud.h"
#include "constants.h"
#include "gamedef.h"
#include "settings.h"
#include "content_sao.h"
-#include "util/numeric.h"
+#include "filesys.h"
+#include "log.h"
Player::Player(IGameDef *gamedef):
touching_ground(false),
void Player::deSerialize(std::istream &is, std::string playername)
{
Settings args;
-
- for(;;)
- {
- if(is.eof())
- throw SerializationError
- (("Player::deSerialize(): PlayerArgsEnd of player \"" + playername + "\" not found").c_str());
- std::string line;
- std::getline(is, line);
- std::string trimmedline = trim(line);
- if(trimmedline == "PlayerArgsEnd")
- break;
- args.parseConfigLine(line);
+
+ if (!args.parseConfigLines(is, "PlayerArgsEnd")) {
+ throw SerializationError("PlayerArgsEnd of player " +
+ playername + " not found!");
}
//args.getS32("version"); // Version field value not used
#include "lua_api/l_vmanip.h"
#include "common/c_converter.h"
#include "common/c_content.h"
+#include "util/serialize.h"
#include "server.h"
#include "environment.h"
#include "biome.h"
#include "emerge.h"
#include "mapgen_v7.h"
#include "main.h"
+#include "log.h"
struct EnumString ModApiMapgen::es_BiomeTerrainType[] =
#include "common/c_content.h"
#include "cpp_api/s_async.h"
#include "serialization.h"
+#include "json/json.h"
#include "debug.h"
#include "porting.h"
#include "log.h"
#include "tool.h"
+#include "filesys.h"
#include "settings.h"
#include "main.h" //required for g_settings, g_settings_path
-#include "json/json.h"
// debug(...)
// Writes a line to dstream
--- /dev/null
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "settings.h"
+#include "irrlichttypes_bloated.h"
+#include "exceptions.h"
+#include "jthread/jmutexautolock.h"
+#include "strfnd.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "debug.h"
+#include "log.h"
+#include "util/serialize.h"
+#include "filesys.h"
+#include <cctype>
+
+
+Settings & Settings::operator += (const Settings &other)
+{
+ update(other);
+
+ return *this;
+}
+
+
+Settings & Settings::operator = (const Settings &other)
+{
+ if (&other == this)
+ return *this;
+
+ JMutexAutoLock lock(m_mutex);
+ JMutexAutoLock lock2(other.m_mutex);
+
+ clearNoLock();
+ updateNoLock(other);
+
+ return *this;
+}
+
+
+bool Settings::parseConfigLines(std::istream &is,
+ const std::string &end)
+{
+ JMutexAutoLock lock(m_mutex);
+
+ std::string name, value;
+ bool end_found = false;
+
+ while (is.good() && !end_found) {
+ if (parseConfigObject(is, name, value, end, end_found)) {
+ m_settings[name] = value;
+ }
+ }
+ if (!end.empty() && !end_found) {
+ return false;
+ }
+ return true;
+}
+
+
+bool Settings::readConfigFile(const char *filename)
+{
+ std::ifstream is(filename);
+ if (!is.good())
+ return false;
+
+ JMutexAutoLock lock(m_mutex);
+
+ std::string name, value;
+
+ while (is.good()) {
+ if (parseConfigObject(is, name, value)) {
+ m_settings[name] = value;
+ }
+ }
+
+ return true;
+}
+
+
+void Settings::writeLines(std::ostream &os) const
+{
+ JMutexAutoLock lock(m_mutex);
+
+ for (std::map<std::string, std::string>::const_iterator
+ i = m_settings.begin();
+ i != m_settings.end(); ++i) {
+ os << i->first << " = " << i->second << '\n';
+ }
+}
+
+
+bool Settings::updateConfigFile(const char *filename)
+{
+ std::list<std::string> objects;
+ std::set<std::string> updated;
+ bool changed = false;
+
+ JMutexAutoLock lock(m_mutex);
+
+ // Read the file and check for differences
+ {
+ std::ifstream is(filename);
+ while (is.good()) {
+ getUpdatedConfigObject(is, objects,
+ updated, changed);
+ }
+ }
+
+ // If something not yet determined to have been changed, check if
+ // any new stuff was added
+ if (!changed) {
+ for (std::map<std::string, std::string>::const_iterator
+ i = m_settings.begin();
+ i != m_settings.end(); ++i) {
+ if (updated.find(i->first) == updated.end()) {
+ changed = true;
+ break;
+ }
+ }
+ }
+
+ // If nothing was actually changed, skip writing the file
+ if (!changed) {
+ return true;
+ }
+
+ // Write stuff back
+ {
+ std::ostringstream ss(std::ios_base::binary);
+
+ // Write changes settings
+ for (std::list<std::string>::const_iterator
+ i = objects.begin();
+ i != objects.end(); ++i) {
+ ss << (*i);
+ }
+
+ // Write new settings
+ for (std::map<std::string, std::string>::const_iterator
+ i = m_settings.begin();
+ i != m_settings.end(); ++i) {
+ if (updated.find(i->first) != updated.end())
+ continue;
+ ss << i->first << " = " << i->second << '\n';
+ }
+
+ if (!fs::safeWriteToFile(filename, ss.str())) {
+ errorstream << "Error writing configuration file: \""
+ << filename << "\"" << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+bool Settings::parseCommandLine(int argc, char *argv[],
+ std::map<std::string, ValueSpec> &allowed_options)
+{
+ int nonopt_index = 0;
+ for (int i = 1; i < argc; i++) {
+ std::string arg_name = argv[i];
+ if (arg_name.substr(0, 2) != "--") {
+ // If option doesn't start with -, read it in as nonoptX
+ if (arg_name[0] != '-'){
+ std::string name = "nonopt";
+ name += itos(nonopt_index);
+ set(name, arg_name);
+ nonopt_index++;
+ continue;
+ }
+ errorstream << "Invalid command-line parameter \""
+ << arg_name << "\": --<option> expected." << std::endl;
+ return false;
+ }
+
+ std::string name = arg_name.substr(2);
+
+ std::map<std::string, ValueSpec>::iterator n;
+ n = allowed_options.find(name);
+ if (n == allowed_options.end()) {
+ errorstream << "Unknown command-line parameter \""
+ << arg_name << "\"" << std::endl;
+ return false;
+ }
+
+ ValueType type = n->second.type;
+
+ std::string value = "";
+
+ if (type == VALUETYPE_FLAG) {
+ value = "true";
+ } else {
+ if ((i + 1) >= argc) {
+ errorstream << "Invalid command-line parameter \""
+ << name << "\": missing value" << std::endl;
+ return false;
+ }
+ value = argv[i++];
+ }
+
+ set(name, value);
+ }
+
+ return true;
+}
+
+
+
+/***********
+ * Getters *
+ ***********/
+
+
+std::string Settings::get(const std::string &name) const
+{
+ JMutexAutoLock lock(m_mutex);
+
+ std::map<std::string, std::string>::const_iterator n;
+ if ((n = m_settings.find(name)) == m_settings.end()) {
+ if ((n = m_defaults.find(name)) == m_defaults.end()) {
+ throw SettingNotFoundException("Setting [" + name + "] not found.");
+ }
+ }
+ return n->second;
+}
+
+
+bool Settings::getBool(const std::string &name) const
+{
+ return is_yes(get(name));
+}
+
+
+u16 Settings::getU16(const std::string &name) const
+{
+ return stoi(get(name), 0, 65535);
+}
+
+
+s16 Settings::getS16(const std::string &name) const
+{
+ return stoi(get(name), -32768, 32767);
+}
+
+
+s32 Settings::getS32(const std::string &name) const
+{
+ return stoi(get(name));
+}
+
+
+float Settings::getFloat(const std::string &name) const
+{
+ return stof(get(name));
+}
+
+
+u64 Settings::getU64(const std::string &name) const
+{
+ u64 value = 0;
+ std::string s = get(name);
+ std::istringstream ss(s);
+ ss >> value;
+ return value;
+}
+
+
+v2f Settings::getV2F(const std::string &name) const
+{
+ v2f value;
+ Strfnd f(get(name));
+ f.next("(");
+ value.X = stof(f.next(","));
+ value.Y = stof(f.next(")"));
+ return value;
+}
+
+
+v3f Settings::getV3F(const std::string &name) const
+{
+ v3f value;
+ Strfnd f(get(name));
+ f.next("(");
+ value.X = stof(f.next(","));
+ value.Y = stof(f.next(","));
+ value.Z = stof(f.next(")"));
+ return value;
+}
+
+
+u32 Settings::getFlagStr(const std::string &name, const FlagDesc *flagdesc,
+ u32 *flagmask) const
+{
+ std::string val = get(name);
+ return std::isdigit(val[0])
+ ? stoi(val)
+ : readFlagString(val, flagdesc, flagmask);
+}
+
+
+// N.B. if getStruct() is used to read a non-POD aggregate type,
+// the behavior is undefined.
+bool Settings::getStruct(const std::string &name, const std::string &format,
+ void *out, size_t olen) const
+{
+ std::string valstr;
+
+ try {
+ valstr = get(name);
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+
+ if (!deSerializeStringToStruct(valstr, format, out, olen))
+ return false;
+
+ return true;
+}
+
+
+bool Settings::exists(const std::string &name) const
+{
+ JMutexAutoLock lock(m_mutex);
+
+ return (m_settings.find(name) != m_settings.end() ||
+ m_defaults.find(name) != m_defaults.end());
+}
+
+
+std::vector<std::string> Settings::getNames() const
+{
+ std::vector<std::string> names;
+ for (std::map<std::string, std::string>::const_iterator
+ i = m_settings.begin();
+ i != m_settings.end(); ++i) {
+ names.push_back(i->first);
+ }
+ return names;
+}
+
+
+
+/***************************************
+ * Getters that don't throw exceptions *
+ ***************************************/
+
+
+bool Settings::getNoEx(const std::string &name, std::string &val) const
+{
+ try {
+ val = get(name);
+ return true;
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+bool Settings::getFlag(const std::string &name) const
+{
+ try {
+ return getBool(name);
+ } catch(SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+bool Settings::getFloatNoEx(const std::string &name, float &val) const
+{
+ try {
+ val = getFloat(name);
+ return true;
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+bool Settings::getU16NoEx(const std::string &name, u16 &val) const
+{
+ try {
+ val = getU16(name);
+ return true;
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+bool Settings::getS16NoEx(const std::string &name, s16 &val) const
+{
+ try {
+ val = getS16(name);
+ return true;
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+bool Settings::getS32NoEx(const std::string &name, s32 &val) const
+{
+ try {
+ val = getS32(name);
+ return true;
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+bool Settings::getU64NoEx(const std::string &name, u64 &val) const
+{
+ try {
+ val = getU64(name);
+ return true;
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+bool Settings::getV2FNoEx(const std::string &name, v2f &val) const
+{
+ try {
+ val = getV2F(name);
+ return true;
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+bool Settings::getV3FNoEx(const std::string &name, v3f &val) const
+{
+ try {
+ val = getV3F(name);
+ return true;
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+// N.B. getFlagStrNoEx() does not set val, but merely modifies it. Thus,
+// val must be initialized before using getFlagStrNoEx(). The intention of
+// this is to simplify modifying a flags field from a default value.
+bool Settings::getFlagStrNoEx(const std::string &name, u32 &val, FlagDesc *flagdesc) const
+{
+ try {
+ u32 flags, flagmask;
+
+ flags = getFlagStr(name, flagdesc, &flagmask);
+
+ val &= ~flagmask;
+ val |= flags;
+
+ return true;
+ } catch (SettingNotFoundException &e) {
+ return false;
+ }
+}
+
+
+
+/***********
+ * Setters *
+ ***********/
+
+
+void Settings::set(const std::string &name, std::string value)
+{
+ JMutexAutoLock lock(m_mutex);
+
+ m_settings[name] = value;
+}
+
+
+void Settings::set(const std::string &name, const char *value)
+{
+ JMutexAutoLock lock(m_mutex);
+
+ m_settings[name] = value;
+}
+
+
+void Settings::setDefault(const std::string &name, std::string value)
+{
+ JMutexAutoLock lock(m_mutex);
+
+ m_defaults[name] = value;
+}
+
+
+void Settings::setBool(const std::string &name, bool value)
+{
+ set(name, value ? "true" : "false");
+}
+
+
+void Settings::setS16(const std::string &name, s16 value)
+{
+ set(name, itos(value));
+}
+
+
+void Settings::setS32(const std::string &name, s32 value)
+{
+ set(name, itos(value));
+}
+
+
+void Settings::setU64(const std::string &name, u64 value)
+{
+ std::ostringstream os;
+ os << value;
+ set(name, os.str());
+}
+
+
+void Settings::setFloat(const std::string &name, float value)
+{
+ set(name, ftos(value));
+}
+
+
+void Settings::setV2F(const std::string &name, v2f value)
+{
+ std::ostringstream os;
+ os << "(" << value.X << "," << value.Y << ")";
+ set(name, os.str());
+}
+
+
+void Settings::setV3F(const std::string &name, v3f value)
+{
+ std::ostringstream os;
+ os << "(" << value.X << "," << value.Y << "," << value.Z << ")";
+ set(name, os.str());
+}
+
+
+void Settings::setFlagStr(const std::string &name, u32 flags,
+ const FlagDesc *flagdesc, u32 flagmask)
+{
+ set(name, writeFlagString(flags, flagdesc, flagmask));
+}
+
+
+bool Settings::setStruct(const std::string &name, const std::string &format, void *value)
+{
+ std::string structstr;
+ if (!serializeStructToString(&structstr, format, value))
+ return false;
+
+ set(name, structstr);
+ return true;
+}
+
+
+bool Settings::remove(const std::string &name)
+{
+ JMutexAutoLock lock(m_mutex);
+ return m_settings.erase(name);
+}
+
+
+void Settings::clear()
+{
+ JMutexAutoLock lock(m_mutex);
+ clearNoLock();
+}
+
+
+void Settings::updateValue(const Settings &other, const std::string &name)
+{
+ if (&other == this)
+ return;
+
+ JMutexAutoLock lock(m_mutex);
+
+ try {
+ std::string val = other.get(name);
+ m_settings[name] = val;
+ } catch (SettingNotFoundException &e) {
+ }
+}
+
+
+void Settings::update(const Settings &other)
+{
+ if (&other == this)
+ return;
+
+ JMutexAutoLock lock(m_mutex);
+ JMutexAutoLock lock2(other.m_mutex);
+
+ updateNoLock(other);
+}
+
+
+inline bool Settings::parseConfigObject(std::istream &is,
+ std::string &name, std::string &value)
+{
+ bool end_found = false;
+ return parseConfigObject(is, name, value, "", end_found);
+}
+
+
+// NOTE: This function might be expanded to allow multi-line settings.
+bool Settings::parseConfigObject(std::istream &is,
+ std::string &name, std::string &value,
+ const std::string &end, bool &end_found)
+{
+ std::string line;
+ std::getline(is, line);
+ std::string trimmed_line = trim(line);
+
+ // Ignore empty lines and comments
+ if (trimmed_line.empty() || trimmed_line[0] == '#') {
+ value = trimmed_line;
+ return false;
+ }
+ if (trimmed_line == end) {
+ end_found = true;
+ return false;
+ }
+
+ Strfnd sf(trimmed_line);
+
+ name = trim(sf.next("="));
+ if (name.empty()) {
+ value = trimmed_line;
+ return false;
+ }
+
+ value = trim(sf.next("\n"));
+
+ return true;
+}
+
+
+void Settings::getUpdatedConfigObject(std::istream &is,
+ std::list<std::string> &dst,
+ std::set<std::string> &updated,
+ bool &changed)
+{
+ std::string name, value;
+ if (!parseConfigObject(is, name, value)) {
+ dst.push_back(value + '\n');
+ return;
+ }
+
+ if (m_settings.find(name) != m_settings.end()) {
+ std::string new_value = m_settings[name];
+
+ if (new_value != value) {
+ changed = true;
+ }
+
+ dst.push_back(name + " = " + new_value + '\n');
+ updated.insert(name);
+ } else { // File contains a setting which is not in m_settings
+ changed = true;
+ }
+}
+
+
+void Settings::updateNoLock(const Settings &other)
+{
+ m_settings.insert(other.m_settings.begin(), other.m_settings.end());
+ m_defaults.insert(other.m_defaults.begin(), other.m_defaults.end());
+}
+
+
+void Settings::clearNoLock()
+{
+ m_settings.clear();
+ m_defaults.clear();
+}
+
#define SETTINGS_HEADER
#include "irrlichttypes_bloated.h"
-#include "exceptions.h"
-#include <string>
-#include "jthread/jmutex.h"
-#include "jthread/jmutexautolock.h"
-#include "strfnd.h"
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include "debug.h"
-#include "log.h"
#include "util/string.h"
-#include "util/serialize.h"
-#include <list>
+#include "jthread/jmutex.h"
+#include <string>
#include <map>
+#include <list>
#include <set>
-#include "filesys.h"
-#include <cctype>
enum ValueType
{
const char *help;
};
+
class Settings
{
public:
- Settings()
- {
- }
-
- void writeLines(std::ostream &os) const
- {
- JMutexAutoLock lock(m_mutex);
-
- for(std::map<std::string, std::string>::const_iterator
- i = m_settings.begin();
- i != m_settings.end(); ++i)
- {
- std::string name = i->first;
- std::string value = i->second;
- os<<name<<" = "<<value<<"\n";
- }
- }
-
- // return all keys used
- std::vector<std::string> getNames() const
- {
- std::vector<std::string> names;
- for(std::map<std::string, std::string>::const_iterator
- i = m_settings.begin();
- i != m_settings.end(); ++i)
- {
- names.push_back(i->first);
- }
- return names;
- }
-
- // remove a setting
- bool remove(const std::string &name)
- {
- return m_settings.erase(name);
- }
-
-
- bool parseConfigLine(const std::string &line)
- {
- JMutexAutoLock lock(m_mutex);
-
- std::string trimmedline = trim(line);
-
- // Ignore empty lines and comments
- if(trimmedline.size() == 0 || trimmedline[0] == '#')
- return true;
-
- //infostream<<"trimmedline=\""<<trimmedline<<"\""<<std::endl;
-
- Strfnd sf(trim(line));
-
- std::string name = sf.next("=");
- name = trim(name);
-
- if(name == "")
- return true;
-
- std::string value = sf.next("\n");
- value = trim(value);
-
- /*infostream<<"Config name=\""<<name<<"\" value=\""
- <<value<<"\""<<std::endl;*/
-
- m_settings[name] = value;
-
- return true;
- }
-
- void parseConfigLines(std::istream &is, const std::string &endstring)
- {
- for(;;){
- if(is.eof())
- break;
- std::string line;
- std::getline(is, line);
- std::string trimmedline = trim(line);
- if(endstring != ""){
- if(trimmedline == endstring)
- break;
- }
- parseConfigLine(line);
- }
- }
-
- // Returns false on EOF
- bool parseConfigObject(std::istream &is)
- {
- if(is.eof())
- return false;
-
- /*
- NOTE: This function might be expanded to allow multi-line
- settings.
- */
- std::string line;
- std::getline(is, line);
- //infostream<<"got line: \""<<line<<"\""<<std::endl;
-
- return parseConfigLine(line);
- }
-
- /*
- Read configuration file
-
- Returns true on success
- */
- bool readConfigFile(const char *filename)
- {
- std::ifstream is(filename);
- if(is.good() == false)
- return false;
-
- /*infostream<<"Parsing configuration file: \""
- <<filename<<"\""<<std::endl;*/
-
- while(parseConfigObject(is));
-
- return true;
- }
-
- /*
- Reads a configuration object from stream (usually a single line)
- and adds it to dst.
-
- Preserves comments and empty lines.
-
- Settings that were added to dst are also added to updated.
- key of updated is setting name, value of updated is dummy.
-
- Returns false on EOF
- */
- bool getUpdatedConfigObject(std::istream &is,
- std::list<std::string> &dst,
- std::set<std::string> &updated,
- bool &value_changed)
- {
- JMutexAutoLock lock(m_mutex);
-
- if(is.eof())
- return false;
-
- // NOTE: This function will be expanded to allow multi-line settings
- std::string line;
- std::getline(is, line);
-
- std::string trimmedline = trim(line);
-
- std::string line_end = "";
- if(is.eof() == false)
- line_end = "\n";
-
- // Ignore empty lines and comments
- if(trimmedline.size() == 0 || trimmedline[0] == '#')
- {
- dst.push_back(line+line_end);
- return true;
- }
-
- Strfnd sf(trim(line));
-
- std::string name = sf.next("=");
- name = trim(name);
-
- if(name == "")
- {
- dst.push_back(line+line_end);
- return true;
- }
-
- std::string value = sf.next("\n");
- value = trim(value);
-
- if(m_settings.find(name) != m_settings.end())
- {
- std::string newvalue = m_settings[name];
-
- if(newvalue != value)
- {
- infostream<<"Changing value of \""<<name<<"\" = \""
- <<value<<"\" -> \""<<newvalue<<"\""
- <<std::endl;
- value_changed = true;
- }
-
- dst.push_back(name + " = " + newvalue + line_end);
-
- updated.insert(name);
- }
- else //file contains a setting which is not in m_settings
- value_changed=true;
-
- return true;
- }
+ Settings() {}
- /*
- Updates configuration file
+ Settings & operator += (const Settings &other);
+ Settings & operator = (const Settings &other);
- Returns true on success
- */
- bool updateConfigFile(const char *filename)
- {
- infostream<<"Updating configuration file: \""
- <<filename<<"\""<<std::endl;
-
- std::list<std::string> objects;
- std::set<std::string> updated;
- bool something_actually_changed = false;
-
- // Read and modify stuff
- {
- std::ifstream is(filename);
- if(is.good() == false)
- {
- infostream<<"updateConfigFile():"
- " Error opening configuration file"
- " for reading: \""
- <<filename<<"\""<<std::endl;
- }
- else
- {
- while(getUpdatedConfigObject(is, objects, updated,
- something_actually_changed));
- }
- }
-
- JMutexAutoLock lock(m_mutex);
-
- // If something not yet determined to have been changed, check if
- // any new stuff was added
- if(!something_actually_changed){
- for(std::map<std::string, std::string>::const_iterator
- i = m_settings.begin();
- i != m_settings.end(); ++i)
- {
- if(updated.find(i->first) != updated.end())
- continue;
- something_actually_changed = true;
- break;
- }
- }
-
- // If nothing was actually changed, skip writing the file
- if(!something_actually_changed){
- infostream<<"Skipping writing of "<<filename
- <<" because content wouldn't be modified"<<std::endl;
- return true;
- }
-
- // Write stuff back
- {
- std::ostringstream ss(std::ios_base::binary);
-
- /*
- Write updated stuff
- */
- for(std::list<std::string>::const_iterator
- i = objects.begin();
- i != objects.end(); ++i)
- {
- ss<<(*i);
- }
-
- /*
- Write stuff that was not already in the file
- */
- for(std::map<std::string, std::string>::const_iterator
- i = m_settings.begin();
- i != m_settings.end(); ++i)
- {
- if(updated.find(i->first) != updated.end())
- continue;
- std::string name = i->first;
- std::string value = i->second;
- infostream<<"Adding \""<<name<<"\" = \""<<value<<"\""
- <<std::endl;
- ss<<name<<" = "<<value<<"\n";
- }
-
- if(!fs::safeWriteToFile(filename, ss.str()))
- {
- errorstream<<"Error writing configuration file: \""
- <<filename<<"\""<<std::endl;
- return false;
- }
- }
-
- return true;
- }
- /*
- NOTE: Types of allowed_options are ignored
+ /***********************
+ * Reading and writing *
+ ***********************/
- returns true on success
- */
+ // Read configuration file. Returns success.
+ bool readConfigFile(const char *filename);
+ //Updates configuration file. Returns success.
+ bool updateConfigFile(const char *filename);
+ // NOTE: Types of allowed_options are ignored. Returns success.
bool parseCommandLine(int argc, char *argv[],
- std::map<std::string, ValueSpec> &allowed_options)
- {
- int nonopt_index = 0;
- int i=1;
- for(;;)
- {
- if(i >= argc)
- break;
- std::string argname = argv[i];
- if(argname.substr(0, 2) != "--")
- {
- // If option doesn't start with -, read it in as nonoptX
- if(argname[0] != '-'){
- std::string name = "nonopt";
- name += itos(nonopt_index);
- set(name, argname);
- nonopt_index++;
- i++;
- continue;
- }
- errorstream<<"Invalid command-line parameter \""
- <<argname<<"\": --<option> expected."<<std::endl;
- return false;
- }
- i++;
-
- std::string name = argname.substr(2);
-
- std::map<std::string, ValueSpec>::iterator n;
- n = allowed_options.find(name);
- if(n == allowed_options.end())
- {
- errorstream<<"Unknown command-line parameter \""
- <<argname<<"\""<<std::endl;
- return false;
- }
-
- ValueType type = n->second.type;
-
- std::string value = "";
-
- if(type == VALUETYPE_FLAG)
- {
- value = "true";
- }
- else
- {
- if(i >= argc)
- {
- errorstream<<"Invalid command-line parameter \""
- <<name<<"\": missing value"<<std::endl;
- return false;
- }
- value = argv[i];
- i++;
- }
-
-
- infostream<<"Valid command-line parameter: \""
- <<name<<"\" = \""<<value<<"\""
- <<std::endl;
- set(name, value);
- }
-
- return true;
- }
-
- void set(const std::string &name, std::string value)
- {
- JMutexAutoLock lock(m_mutex);
-
- m_settings[name] = value;
- }
-
- void set(const std::string &name, const char *value)
- {
- JMutexAutoLock lock(m_mutex);
-
- m_settings[name] = value;
- }
-
-
- void setDefault(const std::string &name, std::string value)
- {
- JMutexAutoLock lock(m_mutex);
-
- m_defaults[name] = value;
- }
-
- bool exists(const std::string &name) const
- {
- JMutexAutoLock lock(m_mutex);
-
- return (m_settings.find(name) != m_settings.end() ||
- m_defaults.find(name) != m_defaults.end());
- }
-
- std::string get(const std::string &name) const
- {
- JMutexAutoLock lock(m_mutex);
-
- std::map<std::string, std::string>::const_iterator n;
- if ((n = m_settings.find(name)) == m_settings.end())
- if ((n = m_defaults.find(name)) == m_defaults.end())
- throw SettingNotFoundException(("Setting [" + name + "] not found ").c_str());
-
- return n->second;
- }
-
- //////////// Get setting
- bool getBool(const std::string &name) const
- {
- return is_yes(get(name));
- }
-
- bool getFlag(const std::string &name) const
- {
- try {
- return getBool(name);
- } catch(SettingNotFoundException &e) {
- return false;
- }
- }
-
- float getFloat(const std::string &name) const
- {
- return stof(get(name));
- }
-
- u16 getU16(const std::string &name) const
- {
- return stoi(get(name), 0, 65535);
- }
-
- s16 getS16(const std::string &name) const
- {
- return stoi(get(name), -32768, 32767);
- }
-
- s32 getS32(const std::string &name) const
- {
- return stoi(get(name));
- }
-
- v3f getV3F(const std::string &name) const
- {
- v3f value;
- Strfnd f(get(name));
- f.next("(");
- value.X = stof(f.next(","));
- value.Y = stof(f.next(","));
- value.Z = stof(f.next(")"));
- return value;
- }
-
- v2f getV2F(const std::string &name) const
- {
- v2f value;
- Strfnd f(get(name));
- f.next("(");
- value.X = stof(f.next(","));
- value.Y = stof(f.next(")"));
- return value;
- }
-
- u64 getU64(const std::string &name) const
- {
- u64 value = 0;
- std::string s = get(name);
- std::istringstream ss(s);
- ss >> value;
- return value;
- }
-
+ std::map<std::string, ValueSpec> &allowed_options);
+ bool parseConfigLines(std::istream &is, const std::string &end = "");
+ void writeLines(std::ostream &os) const;
+
+
+ /***********
+ * Getters *
+ ***********/
+
+ std::string get(const std::string &name) const;
+ bool getBool(const std::string &name) const;
+ u16 getU16(const std::string &name) const;
+ s16 getS16(const std::string &name) const;
+ s32 getS32(const std::string &name) const;
+ u64 getU64(const std::string &name) const;
+ float getFloat(const std::string &name) const;
+ v2f getV2F(const std::string &name) const;
+ v3f getV3F(const std::string &name) const;
u32 getFlagStr(const std::string &name, const FlagDesc *flagdesc,
- u32 *flagmask) const
- {
- std::string val = get(name);
- return std::isdigit(val[0])
- ? stoi(val)
- : readFlagString(val, flagdesc, flagmask);
- }
-
+ u32 *flagmask) const;
// N.B. if getStruct() is used to read a non-POD aggregate type,
// the behavior is undefined.
bool getStruct(const std::string &name, const std::string &format,
- void *out, size_t olen) const
- {
- std::string valstr;
-
- try {
- valstr = get(name);
- } catch (SettingNotFoundException &e) {
- return false;
- }
-
- if (!deSerializeStringToStruct(valstr, format, out, olen))
- return false;
-
- return true;
- }
-
- //////////// Try to get value, no exception thrown
- bool getNoEx(const std::string &name, std::string &val) const
- {
- try {
- val = get(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
+ void *out, size_t olen) const;
+ // return all keys used
+ std::vector<std::string> getNames() const;
+ bool exists(const std::string &name) const;
+
+
+ /***************************************
+ * Getters that don't throw exceptions *
+ ***************************************/
+
+ bool getNoEx(const std::string &name, std::string &val) const;
+ bool getFlag(const std::string &name) const;
+ bool getU16NoEx(const std::string &name, u16 &val) const;
+ bool getS16NoEx(const std::string &name, s16 &val) const;
+ bool getS32NoEx(const std::string &name, s32 &val) const;
+ bool getU64NoEx(const std::string &name, u64 &val) const;
+ bool getFloatNoEx(const std::string &name, float &val) const;
+ bool getV2FNoEx(const std::string &name, v2f &val) const;
+ bool getV3FNoEx(const std::string &name, v3f &val) const;
// N.B. getFlagStrNoEx() does not set val, but merely modifies it. Thus,
// val must be initialized before using getFlagStrNoEx(). The intention of
// this is to simplify modifying a flags field from a default value.
- bool getFlagStrNoEx(const std::string &name, u32 &val, FlagDesc *flagdesc) const
- {
- try {
- u32 flags, flagmask;
-
- flags = getFlagStr(name, flagdesc, &flagmask);
-
- val &= ~flagmask;
- val |= flags;
-
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- bool getFloatNoEx(const std::string &name, float &val) const
- {
- try {
- val = getFloat(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- bool getU16NoEx(const std::string &name, int &val) const
- {
- try {
- val = getU16(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- bool getU16NoEx(const std::string &name, u16 &val) const
- {
- try {
- val = getU16(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- bool getS16NoEx(const std::string &name, int &val) const
- {
- try {
- val = getU16(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- bool getS16NoEx(const std::string &name, s16 &val) const
- {
- try {
- val = getS16(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- bool getS32NoEx(const std::string &name, s32 &val) const
- {
- try {
- val = getS32(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- bool getV3FNoEx(const std::string &name, v3f &val) const
- {
- try {
- val = getV3F(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- bool getV2FNoEx(const std::string &name, v2f &val) const
- {
- try {
- val = getV2F(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- bool getU64NoEx(const std::string &name, u64 &val) const
- {
- try {
- val = getU64(name);
- return true;
- } catch (SettingNotFoundException &e) {
- return false;
- }
- }
-
- //////////// Set setting
-
+ bool getFlagStrNoEx(const std::string &name, u32 &val, FlagDesc *flagdesc) const;
+
+
+ /***********
+ * Setters *
+ ***********/
+
+ void set(const std::string &name, std::string value);
+ void set(const std::string &name, const char *value);
+ void setDefault(const std::string &name, std::string value);
+ void setBool(const std::string &name, bool value);
+ void setS16(const std::string &name, s16 value);
+ void setS32(const std::string &name, s32 value);
+ void setU64(const std::string &name, u64 value);
+ void setFloat(const std::string &name, float value);
+ void setV2F(const std::string &name, v2f value);
+ void setV3F(const std::string &name, v3f value);
+ void setFlagStr(const std::string &name, u32 flags,
+ const FlagDesc *flagdesc, u32 flagmask);
// N.B. if setStruct() is used to write a non-POD aggregate type,
// the behavior is undefined.
- bool setStruct(const std::string &name, const std::string &format, void *value)
- {
- std::string structstr;
- if (!serializeStructToString(&structstr, format, value))
- return false;
-
- set(name, structstr);
- return true;
- }
+ bool setStruct(const std::string &name, const std::string &format, void *value);
- void setFlagStr(const std::string &name, u32 flags,
- const FlagDesc *flagdesc, u32 flagmask)
- {
- set(name, writeFlagString(flags, flagdesc, flagmask));
- }
-
- void setBool(const std::string &name, bool value)
- {
- set(name, value ? "true" : "false");
- }
-
- void setFloat(const std::string &name, float value)
- {
- set(name, ftos(value));
- }
-
- void setV3F(const std::string &name, v3f value)
- {
- std::ostringstream os;
- os<<"("<<value.X<<","<<value.Y<<","<<value.Z<<")";
- set(name, os.str());
- }
-
- void setV2F(const std::string &name, v2f value)
- {
- std::ostringstream os;
- os<<"("<<value.X<<","<<value.Y<<")";
- set(name, os.str());
- }
-
- void setS16(const std::string &name, s16 value)
- {
- set(name, itos(value));
- }
-
- void setS32(const std::string &name, s32 value)
- {
- set(name, itos(value));
- }
-
- void setU64(const std::string &name, u64 value)
- {
- std::ostringstream os;
- os<<value;
- set(name, os.str());
- }
-
- void clear()
- {
- JMutexAutoLock lock(m_mutex);
- clearNoLock();
- }
-
- void updateValue(const Settings &other, const std::string &name)
- {
- if (&other == this)
- return;
-
- JMutexAutoLock lock(m_mutex);
-
- try {
- std::string val = other.get(name);
- m_settings[name] = val;
- } catch (SettingNotFoundException &e) {
- }
- }
-
- void update(const Settings &other)
- {
- if (&other == this)
- return;
-
- JMutexAutoLock lock(m_mutex);
- JMutexAutoLock lock2(other.m_mutex);
-
- updateNoLock(other);
- }
-
- Settings & operator+=(const Settings &other)
- {
- update(other);
-
- return *this;
- }
-
- Settings & operator=(const Settings &other)
- {
- if (&other == this)
- return *this;
-
- JMutexAutoLock lock(m_mutex);
- JMutexAutoLock lock2(other.m_mutex);
-
- clearNoLock();
- updateNoLock(other);
+ // remove a setting
+ bool remove(const std::string &name);
+ void clear();
+ void updateValue(const Settings &other, const std::string &name);
+ void update(const Settings &other);
- return *this;
- }
private:
+ /***********************
+ * Reading and writing *
+ ***********************/
+
+ bool parseConfigObject(std::istream &is,
+ std::string &name, std::string &value);
+ bool parseConfigObject(std::istream &is,
+ std::string &name, std::string &value,
+ const std::string &end, bool &end_found);
+ /*
+ * Reads a configuration object from stream (usually a single line)
+ * and adds it to dst.
+ * Preserves comments and empty lines.
+ * Setting names that were added to dst are also added to updated.
+ */
+ void getUpdatedConfigObject(std::istream &is,
+ std::list<std::string> &dst,
+ std::set<std::string> &updated,
+ bool &changed);
- void updateNoLock(const Settings &other)
- {
- m_settings.insert(other.m_settings.begin(), other.m_settings.end());
- m_defaults.insert(other.m_defaults.begin(), other.m_defaults.end());
- }
- void clearNoLock()
- {
- m_settings.clear();
- m_defaults.clear();
- }
+ void updateNoLock(const Settings &other);
+ void clearNoLock();
std::map<std::string, std::string> m_settings;
#include "socket.h"
+#include <stdio.h>
+#include <iostream>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sstream>
+#include <iomanip>
+#include "util/string.h"
+#include "util/numeric.h"
+#include "constants.h"
+#include "debug.h"
+#include "settings.h"
+#include "log.h"
+#include "main.h" // for g_settings
+
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
typedef int socket_t;
#endif
-#include "constants.h"
-#include "debug.h"
-#include "settings.h"
-#include "main.h" // for g_settings
-#include <stdio.h>
-#include <iostream>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sstream>
-#include <iomanip>
-#include "util/string.h"
-#include "util/numeric.h"
-
// Set to true to enable verbose debug output
bool socket_enable_debug_output = false;
{
Settings s;
// Test reading of settings
- s.parseConfigLine("leet = 1337");
- s.parseConfigLine("leetleet = 13371337");
- s.parseConfigLine("leetleet_neg = -13371337");
- s.parseConfigLine("floaty_thing = 1.1");
- s.parseConfigLine("stringy_thing = asd /( ¤%&(/\" BLÖÄRP");
- s.parseConfigLine("coord = (1, 2, 4.5)");
+ std::istringstream is(
+ "leet = 1337\n"
+ "leetleet = 13371337\n"
+ "leetleet_neg = -13371337\n"
+ "floaty_thing = 1.1\n"
+ "stringy_thing = asd /( ¤%&(/\" BLÖÄRP\n"
+ "coord = (1, 2, 4.5)");
+ s.parseConfigLines(is);
UASSERT(s.getS32("leet") == 1337);
UASSERT(s.getS16("leetleet") == 32767);
UASSERT(s.getS16("leetleet_neg") == -32768);
*/
#include "tile.h"
+
+#include <ICameraSceneNode.h>
+#include "util/string.h"
+#include "util/container.h"
+#include "util/thread.h"
+#include "util/numeric.h"
#include "irrlichttypes_extrabloated.h"
#include "debug.h"
#include "main.h" // for g_settings
#include "filesys.h"
#include "settings.h"
#include "mesh.h"
-#include <ICameraSceneNode.h>
#include "log.h"
#include "gamedef.h"
-#include "util/string.h"
-#include "util/container.h"
-#include "util/thread.h"
-#include "util/numeric.h"
+#include "strfnd.h"
#ifdef __ANDROID__
#include <GLES/gl.h>