1 /* 2 settings.h 3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> 4 */ 5 6 /* 7 This file is part of Freeminer. 8 9 Freeminer is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Freeminer is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Freeminer. If not, see <http://www.gnu.org/licenses/>. 21 */ 22 23 #ifndef SETTINGS_HEADER 24 #define SETTINGS_HEADER 25 26 #include "irrlichttypes_bloated.h" 27 #include "util/string.h" 28 #include "jthread/jmutex.h" 29 #include <string> 30 #include <map> 31 #include <list> 32 #include <set> 33 34 #include "porting.h" 35 #include "json/json.h" // for json config values 36 #include <stdint.h> 37 38 enum ValueType 39 { 40 VALUETYPE_STRING, 41 VALUETYPE_FLAG // Doesn't take any arguments 42 }; 43 44 struct ValueSpec 45 { 46 ValueSpec(ValueType a_type, const char *a_help=NULL) 47 { 48 type = a_type; 49 help = a_help; 50 } 51 ValueType type; 52 const char *help; 53 }; 54 55 56 class Settings 57 { 58 public: Settings()59 Settings() {} 60 61 Settings & operator += (const Settings &other); 62 Settings & operator = (const Settings &other); 63 64 65 /*********************** 66 * Reading and writing * 67 ***********************/ 68 69 // Read configuration file. Returns success. 70 bool readConfigFile(const char *filename); 71 //Updates configuration file. Returns success. 72 bool updateConfigFile(const char *filename); 73 // NOTE: Types of allowed_options are ignored. Returns success. 74 bool parseCommandLine(int argc, char *argv[], 75 std::map<std::string, ValueSpec> &allowed_options); 76 bool parseConfigLines(std::istream &is, const std::string &end = ""); 77 void writeLines(std::ostream &os) const; 78 79 80 /*********** 81 * Getters * 82 ***********/ 83 84 std::string get(const std::string &name) const; 85 bool getBool(const std::string &name) const; 86 u16 getU16(const std::string &name) const; 87 s16 getS16(const std::string &name) const; 88 s32 getS32(const std::string &name) const; 89 u64 getU64(const std::string &name) const; 90 float getFloat(const std::string &name) const; 91 v2f getV2F(const std::string &name) const; 92 v3f getV3F(const std::string &name) const; 93 u32 getFlagStr(const std::string &name, const FlagDesc *flagdesc, 94 u32 *flagmask) const; 95 // N.B. if getStruct() is used to read a non-POD aggregate type, 96 // the behavior is undefined. 97 bool getStruct(const std::string &name, const std::string &format, 98 void *out, size_t olen) const; 99 100 // return all keys used 101 std::vector<std::string> getNames() const; 102 bool exists(const std::string &name) const; 103 104 105 /*************************************** 106 * Getters that don't throw exceptions * 107 ***************************************/ 108 109 bool getNoEx(const std::string &name, std::string &val) const; 110 bool getFlag(const std::string &name) const; 111 bool getU16NoEx(const std::string &name, u16 &val) const; 112 bool getS16NoEx(const std::string &name, s16 &val) const; 113 bool getS32NoEx(const std::string &name, s32 &val) const; 114 bool getU64NoEx(const std::string &name, u64 &val) const; 115 bool getFloatNoEx(const std::string &name, float &val) const; 116 bool getV2FNoEx(const std::string &name, v2f &val) const; 117 bool getV3FNoEx(const std::string &name, v3f &val) const; 118 // N.B. getFlagStrNoEx() does not set val, but merely modifies it. Thus, 119 // val must be initialized before using getFlagStrNoEx(). The intention of 120 // this is to simplify modifying a flags field from a default value. 121 bool getFlagStrNoEx(const std::string &name, u32 &val, FlagDesc *flagdesc) const; 122 123 124 /*********** 125 * Setters * 126 ***********/ 127 128 void set(const std::string &name, std::string value); 129 void set(const std::string &name, const char *value); 130 void setDefault(const std::string &name, std::string value); 131 void setBool(const std::string &name, bool value); 132 void setS16(const std::string &name, s16 value); 133 void setS32(const std::string &name, s32 value); 134 void setU64(const std::string &name, uint64_t value); 135 void setFloat(const std::string &name, float value); 136 void setV2F(const std::string &name, v2f value); 137 void setV3F(const std::string &name, v3f value); 138 void setFlagStr(const std::string &name, u32 flags, 139 const FlagDesc *flagdesc, u32 flagmask); 140 // N.B. if setStruct() is used to write a non-POD aggregate type, 141 // the behavior is undefined. 142 bool setStruct(const std::string &name, const std::string &format, void *value); 143 // remove a setting 144 bool remove(const std::string &name); 145 void clear(); 146 void updateValue(const Settings &other, const std::string &name); 147 void update(const Settings &other); 148 149 Json::Value getJson(const std::string & name, const Json::Value & def = Json::Value()); 150 void setJson(const std::string & name, const Json::Value & value); 151 152 private: 153 /*********************** 154 * Reading and writing * 155 ***********************/ 156 157 bool parseConfigObject(std::istream &is, 158 std::string &name, std::string &value); 159 bool parseConfigObject(std::istream &is, 160 std::string &name, std::string &value, 161 const std::string &end, bool &end_found); 162 /* 163 * Reads a configuration object from stream (usually a single line) 164 * and adds it to dst. 165 * Preserves comments and empty lines. 166 * Setting names that were added to dst are also added to updated. 167 */ 168 void getUpdatedConfigObject(std::istream &is, 169 std::list<std::string> &dst, 170 std::set<std::string> &updated, 171 bool &changed); 172 173 174 void updateNoLock(const Settings &other); 175 void clearNoLock(); 176 177 178 std::map<std::string, std::string> m_settings; 179 std::map<std::string, std::string> m_defaults; 180 // All methods that access m_settings/m_defaults directly should lock this. 181 Json::Reader json_reader; 182 Json::FastWriter json_writer; 183 mutable JMutex m_mutex; 184 }; 185 186 extern Settings *g_settings; 187 extern std::string g_settings_path; 188 189 #endif 190