00001 #ifndef GSGL_DATA_config_record_H
00002 #define GSGL_DATA_config_record_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "data/data.hpp"
00038 #include "data/pointer.hpp"
00039 #include "data/string.hpp"
00040 #include "data/list.hpp"
00041 #include "data/dictionary.hpp"
00042 #include "data/file.hpp"
00043
00044 namespace gsgl
00045 {
00046
00047 namespace data
00048 {
00049
00050 class DATA_API global_config;
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 class DATA_API config_record
00061 : public data_object
00062 {
00063 config_record *parent;
00064 gsgl::data::list<config_record> children;
00065
00066 gsgl::string name;
00067 gsgl::string text;
00068 dictionary<gsgl::string, gsgl::string> attributes;
00069
00070 friend class global_config;
00071 global_config *associated_var;
00072
00073 data::shared_pointer<io::file> f;
00074
00075 public:
00076 config_record();
00077 config_record(const config_record &);
00078
00079
00080 explicit config_record(const gsgl::string & fname);
00081
00082 config_record & operator= (const config_record &);
00083
00084 virtual ~config_record();
00085
00086
00087
00088 bool operator== (const config_record &) const;
00089
00090
00091
00092
00093
00094
00095 const io::file & get_file() const;
00096
00097
00098 const io::directory & get_directory() const;
00099
00100
00101 const gsgl::string & get_name() const;
00102 gsgl::string & get_name();
00103
00104
00105 const gsgl::string & get_text() const;
00106 gsgl::string & get_text();
00107
00108
00109 const gsgl::string & get_attribute(const gsgl::string &) const;
00110 gsgl::string & get_attribute(const gsgl::string &);
00111
00112
00113 inline const string & operator[] (const gsgl::string & name) const
00114 {
00115 return get_attribute(name);
00116 }
00117
00118 inline string & operator[] (const gsgl::string & name)
00119 {
00120 return get_attribute(name);
00121 }
00122
00123
00124 const dictionary<gsgl::string, gsgl::string> & get_attributes() const;
00125 dictionary<gsgl::string, gsgl::string> & get_attributes();
00126
00127
00128 const config_record & get_child(const gsgl::string & path) const;
00129 config_record & get_child(const gsgl::string & path);
00130
00131
00132 const list<config_record> & get_children() const;
00133 list<config_record> & get_children();
00134
00135
00136
00137 void override_with(const config_record & cr);
00138
00139
00140 void save();
00141
00142 private:
00143 config_record & find_child(gsgl::data::list<gsgl::string>::iterator & pos_in_path, bool create);
00144
00145 void to_stream(io::text_stream &) const;
00146 void from_stream(io::text_stream &);
00147
00148 void to_stream(io::text_stream &, int indent) const;
00149 void from_stream(io::text_stream &, int & line);
00150 };
00151
00152
00153
00154
00155
00156
00157 class DATA_API global_config
00158 {
00159 friend class config_record;
00160
00161 protected:
00162 static config_record global_config_vars;
00163 config_record & associated_record;
00164
00165 global_config(const gsgl::string & path);
00166 virtual ~global_config();
00167
00168 virtual void assign_from_string(const gsgl::string &) = 0;
00169 virtual gsgl::string get_string() const = 0;
00170
00171 public:
00172
00173
00174 static const config_record & get_config() { return global_config_vars; }
00175
00176
00177 static void override_with(const config_record &);
00178
00179
00180 static void save(const gsgl::string & fname);
00181 };
00182
00183
00184
00185
00186 template <typename T>
00187 class config_variable
00188 : public global_config
00189 {
00190 T value;
00191 public:
00192 config_variable(const gsgl::string & path, const T & value = T())
00193 : global_config(path), value(value)
00194 {
00195
00196 if (!associated_record.get_text().is_empty())
00197 assign_from_string(associated_record.get_text());
00198 else
00199 associated_record.get_text() = get_string();
00200 }
00201
00202 private:
00203
00204 config_variable(const config_variable & cv) : global_config(), value(cv.value) {}
00205
00206
00207 config_variable & operator= (const config_variable & cv) { value = cv.value; }
00208
00209 public:
00210 const T & get_value() const { return value; }
00211 operator const T & () const { return value; }
00212
00213 protected:
00214 virtual void assign_from_string(const gsgl::string &);
00215 virtual gsgl::string get_string() const;
00216 };
00217
00218
00219
00220
00221 template <>
00222 inline void config_variable<gsgl::string>::assign_from_string(const gsgl::string & s)
00223 {
00224 value = s;
00225 }
00226
00227
00228 template <>
00229 inline gsgl::string config_variable<gsgl::string>::get_string() const
00230 {
00231 return value;
00232 }
00233
00234
00235 inline gsgl::string operator+ (const config_variable<gsgl::string> & cv, const wchar_t *str)
00236 {
00237 return cv.get_value() + str;
00238 }
00239
00240
00241 inline gsgl::string operator+ (const config_variable<gsgl::string> & cv, const gsgl::string & str)
00242 {
00243 return cv.get_value() + str;
00244 }
00245
00246
00247 template <>
00248 inline void config_variable<float>::assign_from_string(const gsgl::string & s)
00249 {
00250 value = static_cast<float>(s.to_double());
00251 }
00252
00253
00254 template <>
00255 inline gsgl::string config_variable<float>::get_string() const
00256 {
00257 return gsgl::string::format(L"%f", value);
00258 }
00259
00260
00261 template <>
00262 inline void config_variable<int>::assign_from_string(const gsgl::string & s)
00263 {
00264 value = s.to_int();
00265 }
00266
00267
00268 template <>
00269 inline gsgl::string config_variable<int>::get_string() const
00270 {
00271 return gsgl::string::format(L"%d", value);
00272 }
00273
00274 }
00275
00276 }
00277
00278 #endif