| 1 | #pragma once
|
|---|
| 2 |
|
|---|
| 3 | #include <map>
|
|---|
| 4 | #include <list>
|
|---|
| 5 | #include <string>
|
|---|
| 6 |
|
|---|
| 7 | #include <boost/any.hpp>
|
|---|
| 8 | #include <boost/bind.hpp>
|
|---|
| 9 | #include <boost/function.hpp>
|
|---|
| 10 | #include <boost/shared_ptr.hpp>
|
|---|
| 11 | #include <boost/foreach.hpp>
|
|---|
| 12 |
|
|---|
| 13 | #include <unicode_char.hpp>
|
|---|
| 14 | #include <strEx.h>
|
|---|
| 15 |
|
|---|
| 16 | #include <nscapi/nscapi_core_wrapper.hpp>
|
|---|
| 17 | #include <settings/client/settings_client_interface.hpp>
|
|---|
| 18 |
|
|---|
| 19 | namespace nscapi {
|
|---|
| 20 | namespace settings_helper {
|
|---|
| 21 |
|
|---|
| 22 | typedef boost::shared_ptr<settings_impl_interface> settings_impl_interface_ptr;
|
|---|
| 23 |
|
|---|
| 24 | class key_interface {
|
|---|
| 25 | public:
|
|---|
| 26 | virtual NSCAPI::settings_type get_type() const = 0;
|
|---|
| 27 | virtual std::wstring get_default_as_string() const = 0;
|
|---|
| 28 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path, std::wstring key) const = 0;
|
|---|
| 29 | virtual void notify(settings_impl_interface_ptr core_, std::wstring parent, std::wstring path, std::wstring key) const = 0;
|
|---|
| 30 | };
|
|---|
| 31 | template<class T>
|
|---|
| 32 | class typed_key : public key_interface {
|
|---|
| 33 | public:
|
|---|
| 34 | typed_key(const T& v, bool has_default) : has_default_(has_default), default_value_(boost::any(v)), default_value_as_text_(boost::lexical_cast<std::wstring>(v)) {}
|
|---|
| 35 | typed_key(bool has_default) : has_default_(has_default) {}
|
|---|
| 36 |
|
|---|
| 37 | virtual typed_key* default_value(const T& v) {
|
|---|
| 38 | default_value_ = boost::any(v);
|
|---|
| 39 | default_value_as_text_ = boost::lexical_cast<std::wstring>(v);
|
|---|
| 40 | return this;
|
|---|
| 41 | }
|
|---|
| 42 |
|
|---|
| 43 | virtual std::wstring get_default_as_string() const {
|
|---|
| 44 | return default_value_as_text_;
|
|---|
| 45 | }
|
|---|
| 46 | virtual void update_target(T *value) const = 0;
|
|---|
| 47 | protected:
|
|---|
| 48 | bool has_default_;
|
|---|
| 49 | boost::any default_value_;
|
|---|
| 50 | std::wstring default_value_as_text_;
|
|---|
| 51 | };
|
|---|
| 52 |
|
|---|
| 53 | template<class T>
|
|---|
| 54 | class typed_string_value : public typed_key<T> {
|
|---|
| 55 | public:
|
|---|
| 56 | typed_string_value(const T& v, bool has_default) : typed_key<T>(v, has_default) {}
|
|---|
| 57 | //typed_string_value() : typed_key<T>() {}
|
|---|
| 58 | virtual NSCAPI::settings_type get_type() const {
|
|---|
| 59 | return NSCAPI::key_string;
|
|---|
| 60 | }
|
|---|
| 61 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path, std::wstring key) const {
|
|---|
| 62 | std::wstring dummy(_T("$$DUMMY_VALUE_DO_NOT_USE$$"));
|
|---|
| 63 | if (typed_key<T>::has_default_)
|
|---|
| 64 | dummy = typed_key<T>::default_value_as_text_;
|
|---|
| 65 | std::wstring data = core_->get_string(path, key, dummy);
|
|---|
| 66 | if (typed_key<T>::has_default_ || data != dummy) {
|
|---|
| 67 | T value = boost::lexical_cast<T>(data);
|
|---|
| 68 | update_target(&value);
|
|---|
| 69 | }
|
|---|
| 70 | }
|
|---|
| 71 | virtual void notify(settings_impl_interface_ptr core_, std::wstring parent, std::wstring path, std::wstring key) const {
|
|---|
| 72 | std::wstring dummy(_T("$$DUMMY_VALUE_DO_NOT_USE$$"));
|
|---|
| 73 | if (typed_key<T>::has_default_)
|
|---|
| 74 | dummy = typed_key<T>::default_value_as_text_;
|
|---|
| 75 | std::wstring data = core_->get_string(parent, key, dummy);
|
|---|
| 76 | if (typed_key<T>::has_default_ || data != dummy)
|
|---|
| 77 | dummy = data;
|
|---|
| 78 | data = core_->get_string(path, key, dummy);
|
|---|
| 79 | if (typed_key<T>::has_default_ || data != dummy) {
|
|---|
| 80 | T value = boost::lexical_cast<T>(data);
|
|---|
| 81 | update_target(&value);
|
|---|
| 82 | }
|
|---|
| 83 | }
|
|---|
| 84 | };
|
|---|
| 85 | template<class T>
|
|---|
| 86 | class typed_path_value : public typed_key<T> {
|
|---|
| 87 | public:
|
|---|
| 88 | typed_path_value(const T& v, bool has_default) : typed_key<T>(v, has_default) {}
|
|---|
| 89 | virtual NSCAPI::settings_type get_type() const {
|
|---|
| 90 | return NSCAPI::key_string;
|
|---|
| 91 | }
|
|---|
| 92 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path, std::wstring key) const {
|
|---|
| 93 | std::wstring dummy(_T("$$DUMMY_VALUE_DO_NOT_USE$$"));
|
|---|
| 94 | if (typed_key<T>::has_default_)
|
|---|
| 95 | dummy = typed_key<T>::default_value_as_text_;
|
|---|
| 96 | std::wstring data = core_->get_string(path, key, dummy);
|
|---|
| 97 | if (typed_key<T>::has_default_ || data != dummy) {
|
|---|
| 98 | T value = boost::lexical_cast<T>(core_->expand_path(data));
|
|---|
| 99 | update_target(&value);
|
|---|
| 100 | }
|
|---|
| 101 | }
|
|---|
| 102 | virtual void notify(settings_impl_interface_ptr core_, std::wstring parent, std::wstring path, std::wstring key) const {
|
|---|
| 103 | std::wstring dummy(_T("$$DUMMY_VALUE_DO_NOT_USE$$"));
|
|---|
| 104 | if (typed_key<T>::has_default_)
|
|---|
| 105 | dummy = typed_key<T>::default_value_as_text_;
|
|---|
| 106 | std::wstring data = core_->get_string(parent, key, dummy);
|
|---|
| 107 | if (typed_key<T>::has_default_ || data != dummy)
|
|---|
| 108 | dummy = data;
|
|---|
| 109 | data = core_->get_string(path, key, dummy);
|
|---|
| 110 | if (typed_key<T>::has_default_ || data != dummy) {
|
|---|
| 111 | T value = boost::lexical_cast<T>(core_->expand_path(data));
|
|---|
| 112 | update_target(&value);
|
|---|
| 113 | }
|
|---|
| 114 | }
|
|---|
| 115 | };
|
|---|
| 116 |
|
|---|
| 117 | template<class T>
|
|---|
| 118 | class typed_int_value : public typed_key<T> {
|
|---|
| 119 | public:
|
|---|
| 120 | typed_int_value(const T& v, bool has_default) : typed_key<T>(v, has_default), default_value_as_int_(boost::lexical_cast<int>(v)) {}
|
|---|
| 121 | typed_key<T>* default_value(const T& v) {
|
|---|
| 122 | typed_key<T>::default_value(v);
|
|---|
| 123 | default_value_as_int_ = boost::lexical_cast<int>(v);
|
|---|
| 124 | return this;
|
|---|
| 125 | }
|
|---|
| 126 | virtual NSCAPI::settings_type get_type() const {
|
|---|
| 127 | return NSCAPI::key_integer;
|
|---|
| 128 | }
|
|---|
| 129 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path, std::wstring key) const {
|
|---|
| 130 | int dummy = -1;
|
|---|
| 131 | if (typed_key<T>::has_default_)
|
|---|
| 132 | dummy = default_value_as_int_;
|
|---|
| 133 | int val = core_->get_int(path, key, dummy);
|
|---|
| 134 | if (!typed_key<T>::has_default_ && val == dummy) {
|
|---|
| 135 | dummy = -2;
|
|---|
| 136 | val = core_->get_int(path, key, dummy);
|
|---|
| 137 | if (val == dummy)
|
|---|
| 138 | return;
|
|---|
| 139 | }
|
|---|
| 140 | T value = static_cast<T>(val);
|
|---|
| 141 | update_target(&value);
|
|---|
| 142 | }
|
|---|
| 143 | virtual void notify(settings_impl_interface_ptr core_, std::wstring parent, std::wstring path, std::wstring key) const {
|
|---|
| 144 | if (typed_key<T>::has_default_) {
|
|---|
| 145 | T default_value = static_cast<T>(core_->get_int(parent, key, default_value_as_int_));
|
|---|
| 146 | T value = static_cast<T>(core_->get_int(path, key, default_value));
|
|---|
| 147 | update_target(&value);
|
|---|
| 148 | } else {
|
|---|
| 149 | int dummy = -1;
|
|---|
| 150 | int defval = core_->get_int(path, key, dummy);
|
|---|
| 151 | if (defval == dummy) {
|
|---|
| 152 | dummy = -2;
|
|---|
| 153 | defval = core_->get_int(path, key, dummy);
|
|---|
| 154 | }
|
|---|
| 155 | if (defval != dummy) {
|
|---|
| 156 | T value = static_cast<T>(core_->get_int(path, key, defval));
|
|---|
| 157 | update_target(&value);
|
|---|
| 158 | }
|
|---|
| 159 | dummy = -1;
|
|---|
| 160 | int val = core_->get_int(path, key, dummy);
|
|---|
| 161 | if (val == dummy) {
|
|---|
| 162 | dummy = -2;
|
|---|
| 163 | val = core_->get_int(path, key, dummy);
|
|---|
| 164 | if (val == dummy)
|
|---|
| 165 | return;
|
|---|
| 166 | }
|
|---|
| 167 | T value = static_cast<T>(val);
|
|---|
| 168 | update_target(&value);
|
|---|
| 169 | }
|
|---|
| 170 | }
|
|---|
| 171 | protected:
|
|---|
| 172 | int default_value_as_int_;
|
|---|
| 173 | };
|
|---|
| 174 | template<class T>
|
|---|
| 175 | class typed_bool_value : public typed_int_value<T> {
|
|---|
| 176 | public:
|
|---|
| 177 | typed_bool_value(const T& v, bool has_default) : typed_int_value<T>(v, has_default) {}
|
|---|
| 178 | virtual NSCAPI::settings_type get_type() const {
|
|---|
| 179 | return NSCAPI::key_bool;
|
|---|
| 180 | }
|
|---|
| 181 | // TODO: FIXME: Add support for has_default
|
|---|
| 182 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path, std::wstring key) const {
|
|---|
| 183 | T value = static_cast<T>(core_->get_bool(path, key, typed_int_value<T>::default_value_as_int_==1));
|
|---|
| 184 | update_target(&value);
|
|---|
| 185 | }
|
|---|
| 186 | virtual void notify(settings_impl_interface_ptr core_, std::wstring parent, std::wstring path, std::wstring key) const {
|
|---|
| 187 | T default_value = static_cast<T>(core_->get_bool(parent, key, typed_int_value<T>::default_value_as_int_==1));
|
|---|
| 188 | T value = static_cast<T>(core_->get_bool(path, key, default_value));
|
|---|
| 189 | update_target(&value);
|
|---|
| 190 | }
|
|---|
| 191 | };
|
|---|
| 192 |
|
|---|
| 193 | template<class T, class TBase>
|
|---|
| 194 | class typed_key_value : public TBase {
|
|---|
| 195 | public:
|
|---|
| 196 | typed_key_value(T* store_to, const T& v, bool has_default) : TBase(v, has_default), store_to_(store_to) {}
|
|---|
| 197 |
|
|---|
| 198 | virtual void update_target(T *value) const {
|
|---|
| 199 | if (store_to_)
|
|---|
| 200 | *store_to_ = *value;
|
|---|
| 201 | }
|
|---|
| 202 | protected:
|
|---|
| 203 | T* store_to_;
|
|---|
| 204 | };
|
|---|
| 205 |
|
|---|
| 206 | template<class T, class V, class TBase>
|
|---|
| 207 | class typed_key_entry_in_vector : public TBase {
|
|---|
| 208 | public:
|
|---|
| 209 | typed_key_entry_in_vector(V* store_to, typename V::key_type key, const T& v, bool has_default) : TBase(v, has_default), store_to_(store_to), key_(key) {}
|
|---|
| 210 |
|
|---|
| 211 | virtual void update_target(T *value) const {
|
|---|
| 212 | if (store_to_)
|
|---|
| 213 | (*store_to_)[key_] = *value;
|
|---|
| 214 | }
|
|---|
| 215 | protected:
|
|---|
| 216 | V* store_to_;
|
|---|
| 217 | typename V::key_type key_;
|
|---|
| 218 | };
|
|---|
| 219 |
|
|---|
| 220 | template<class T, class TBase>
|
|---|
| 221 | class typed_key_fun : public TBase {
|
|---|
| 222 | public:
|
|---|
| 223 | typed_key_fun(boost::function<void (T)> callback, const T& v, bool has_default): TBase(v, has_default), callback_(callback) {}
|
|---|
| 224 |
|
|---|
| 225 | virtual void update_target(T *value) const {
|
|---|
| 226 | callback_(*value);
|
|---|
| 227 | }
|
|---|
| 228 | protected:
|
|---|
| 229 | boost::function<void (T)> callback_;
|
|---|
| 230 | };
|
|---|
| 231 |
|
|---|
| 232 | template<typename T>
|
|---|
| 233 | boost::shared_ptr<typed_key_entry_in_vector<std::wstring, T, typed_string_value<std::wstring> > > wstring_vector_key(T *val, typename T::key_type key, std::wstring def) {
|
|---|
| 234 | boost::shared_ptr<typed_key_entry_in_vector<std::wstring, T, typed_string_value<std::wstring> > > r(new typed_key_entry_in_vector<std::wstring, T, typed_string_value<std::wstring> >(val, key, def, true));
|
|---|
| 235 | return r;
|
|---|
| 236 | }
|
|---|
| 237 |
|
|---|
| 238 | typedef typed_key_value<std::wstring, typed_string_value<std::wstring> > wstring_key_type;
|
|---|
| 239 | typedef typed_key_value<std::string, typed_string_value<std::string> > string_key_type;
|
|---|
| 240 | typedef typed_key_value<std::wstring, typed_path_value<std::wstring> > wpath_key_type;
|
|---|
| 241 | typedef typed_key_value<unsigned int, typed_int_value<unsigned int> > uint_key_type;
|
|---|
| 242 | typedef typed_key_value<int, typed_int_value<int> > int_key_type;
|
|---|
| 243 | typedef typed_key_value<bool, typed_bool_value<bool> > bool_key_type;
|
|---|
| 244 |
|
|---|
| 245 | /*
|
|---|
| 246 | template<typename T>
|
|---|
| 247 | typed_key_entry_in_vector<std::wstring, T, typed_string_value<std::wstring> >* wstring_vector_key(T *val, typename T::key_type key, std::wstring def);
|
|---|
| 248 | */
|
|---|
| 249 | boost::shared_ptr<wstring_key_type> wstring_key(std::wstring *val, std::wstring def);
|
|---|
| 250 | boost::shared_ptr<wstring_key_type> wstring_key(std::wstring *val);
|
|---|
| 251 | boost::shared_ptr<string_key_type> string_key(std::string *val, std::string def);
|
|---|
| 252 | boost::shared_ptr<string_key_type> string_key(std::string *val);
|
|---|
| 253 | boost::shared_ptr<int_key_type> int_key(int *val, int def = 0);
|
|---|
| 254 | boost::shared_ptr<uint_key_type> uint_key(unsigned int *val, unsigned int def);
|
|---|
| 255 | boost::shared_ptr<bool_key_type> bool_key(bool *val, bool def);
|
|---|
| 256 | boost::shared_ptr<bool_key_type> bool_key(bool *val);
|
|---|
| 257 | boost::shared_ptr<wpath_key_type> wpath_key(std::wstring *val, std::wstring def);
|
|---|
| 258 | boost::shared_ptr<wpath_key_type> wpath_key(std::wstring *val);
|
|---|
| 259 |
|
|---|
| 260 | template<class T>
|
|---|
| 261 | boost::shared_ptr<typed_key_fun<T, typed_int_value<T> > > int_fun_key(boost::function<void (T)> fun, T def) {
|
|---|
| 262 | boost::shared_ptr<typed_key_fun<T, typed_int_value<T> > > r(new typed_key_fun<T, typed_int_value<T> >(fun, def, true));
|
|---|
| 263 | return r;
|
|---|
| 264 | }
|
|---|
| 265 | template<class T>
|
|---|
| 266 | boost::shared_ptr<typed_key_fun<T, typed_int_value<T> > > int_fun_key(boost::function<void (T)> fun) {
|
|---|
| 267 | boost::shared_ptr<typed_key_fun<T, typed_int_value<T> > > r(new typed_key_fun<T, typed_int_value<T> >(fun, 0, false));
|
|---|
| 268 | return r;
|
|---|
| 269 | }
|
|---|
| 270 | template<class T>
|
|---|
| 271 | boost::shared_ptr<typed_key_fun<T, typed_bool_value<T> > > bool_fun_key(boost::function<void (T)> fun, T def) {
|
|---|
| 272 | boost::shared_ptr<typed_key_fun<T, typed_bool_value<T> > > r(new typed_key_fun<T, typed_bool_value<T> >(fun, def, true));
|
|---|
| 273 | return r;
|
|---|
| 274 | }
|
|---|
| 275 | template<class T>
|
|---|
| 276 | boost::shared_ptr<typed_key_fun<T, typed_string_value<T> > > string_fun_key(boost::function<void (T)> fun, T def) {
|
|---|
| 277 | boost::shared_ptr<typed_key_fun<T, typed_string_value<T> > > r(new typed_key_fun<T, typed_string_value<T> >(fun, def, true));
|
|---|
| 278 | return r;
|
|---|
| 279 | }
|
|---|
| 280 | template<class T>
|
|---|
| 281 | boost::shared_ptr<typed_key_fun<T, typed_string_value<T> > > string_fun_key(boost::function<void (T)> fun) {
|
|---|
| 282 | boost::shared_ptr<typed_key_fun<T, typed_string_value<T> > > r(new typed_key_fun<T, typed_string_value<T> >(fun, T(), false));
|
|---|
| 283 | return r;
|
|---|
| 284 | }
|
|---|
| 285 |
|
|---|
| 286 | class path_interface {
|
|---|
| 287 | public:
|
|---|
| 288 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path) const = 0;
|
|---|
| 289 | };
|
|---|
| 290 |
|
|---|
| 291 | template<class T=std::map<std::wstring,std::wstring> >
|
|---|
| 292 | class typed_path_map : public path_interface {
|
|---|
| 293 | public:
|
|---|
| 294 | typed_path_map(T* store_to) : store_to_(store_to) {}
|
|---|
| 295 |
|
|---|
| 296 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path) const {
|
|---|
| 297 | if (store_to_) {
|
|---|
| 298 | std::list<std::wstring> list = core_->get_keys(path);
|
|---|
| 299 | T result;
|
|---|
| 300 | BOOST_FOREACH(std::wstring key, list) {
|
|---|
| 301 | result[key] = core_->get_string(path, key, _T(""));
|
|---|
| 302 | }
|
|---|
| 303 | *store_to_ = result;
|
|---|
| 304 | }
|
|---|
| 305 | }
|
|---|
| 306 |
|
|---|
| 307 | protected:
|
|---|
| 308 | T* store_to_;
|
|---|
| 309 | };
|
|---|
| 310 |
|
|---|
| 311 | class typed_path_list : public path_interface {
|
|---|
| 312 | public:
|
|---|
| 313 | typed_path_list(std::list<std::wstring>* store_to) : store_to_(store_to) {}
|
|---|
| 314 |
|
|---|
| 315 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path) const {
|
|---|
| 316 | if (store_to_) {
|
|---|
| 317 | *store_to_ = core_->get_keys(path);
|
|---|
| 318 | }
|
|---|
| 319 | }
|
|---|
| 320 |
|
|---|
| 321 | protected:
|
|---|
| 322 | std::list<std::wstring>* store_to_;
|
|---|
| 323 | };
|
|---|
| 324 |
|
|---|
| 325 | class typed_path_fun_value : public path_interface {
|
|---|
| 326 | public:
|
|---|
| 327 | typed_path_fun_value(boost::function<void (std::wstring, std::wstring)> callback) : callback_(callback) {}
|
|---|
| 328 |
|
|---|
| 329 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path) const {
|
|---|
| 330 | if (callback_) {
|
|---|
| 331 | std::list<std::wstring> list = core_->get_keys(path);
|
|---|
| 332 | BOOST_FOREACH(std::wstring key, list) {
|
|---|
| 333 | std::wstring val = core_->get_string(path, key, _T(""));
|
|---|
| 334 | callback_(key, val);
|
|---|
| 335 | }
|
|---|
| 336 | list = core_->get_sections(path);
|
|---|
| 337 | BOOST_FOREACH(std::wstring key, list) {
|
|---|
| 338 | callback_(key, _T(""));
|
|---|
| 339 | }
|
|---|
| 340 | }
|
|---|
| 341 | }
|
|---|
| 342 |
|
|---|
| 343 | protected:
|
|---|
| 344 | boost::function<void (std::wstring, std::wstring)> callback_;
|
|---|
| 345 | };
|
|---|
| 346 |
|
|---|
| 347 | class typed_path_fun : public path_interface {
|
|---|
| 348 | public:
|
|---|
| 349 | typed_path_fun(boost::function<void (std::wstring)> callback) : callback_(callback) {}
|
|---|
| 350 |
|
|---|
| 351 | virtual void notify(settings_impl_interface_ptr core_, std::wstring path) const {
|
|---|
| 352 | if (callback_) {
|
|---|
| 353 | std::list<std::wstring> list = core_->get_keys(path);
|
|---|
| 354 | BOOST_FOREACH(std::wstring key, list) {
|
|---|
| 355 | callback_(key);
|
|---|
| 356 | }
|
|---|
| 357 | }
|
|---|
| 358 | }
|
|---|
| 359 |
|
|---|
| 360 | protected:
|
|---|
| 361 | boost::function<void (std::wstring)> callback_;
|
|---|
| 362 | };
|
|---|
| 363 |
|
|---|
| 364 |
|
|---|
| 365 | boost::shared_ptr<typed_path_fun> fun_path(boost::function<void (std::wstring)> fun);
|
|---|
| 366 | boost::shared_ptr<typed_path_fun_value> fun_values_path(boost::function<void (std::wstring,std::wstring)> fun);
|
|---|
| 367 | boost::shared_ptr<typed_path_map<> > wstring_map_path(std::map<std::wstring,std::wstring> *val);
|
|---|
| 368 | boost::shared_ptr<typed_path_list> wstring_list_path(std::list<std::wstring> *val);
|
|---|
| 369 |
|
|---|
| 370 | struct description_container {
|
|---|
| 371 | std::wstring title;
|
|---|
| 372 | std::wstring description;
|
|---|
| 373 | bool advanced;
|
|---|
| 374 |
|
|---|
| 375 | description_container(std::wstring title, std::wstring description, bool advanced)
|
|---|
| 376 | : title(title)
|
|---|
| 377 | , description(description)
|
|---|
| 378 | , advanced(advanced)
|
|---|
| 379 | {}
|
|---|
| 380 | description_container(std::wstring title, std::wstring description)
|
|---|
| 381 | : title(title)
|
|---|
| 382 | , description(description)
|
|---|
| 383 | , advanced(false)
|
|---|
| 384 | {}
|
|---|
| 385 |
|
|---|
| 386 | description_container(const description_container& obj) {
|
|---|
| 387 | title = obj.title;
|
|---|
| 388 | description = obj.description;
|
|---|
| 389 | advanced = obj.advanced;
|
|---|
| 390 | }
|
|---|
| 391 | description_container& operator=(const description_container& obj) {
|
|---|
| 392 | title = obj.title;
|
|---|
| 393 | description = obj.description;
|
|---|
| 394 | advanced = obj.advanced;
|
|---|
| 395 | return *this;
|
|---|
| 396 | }
|
|---|
| 397 |
|
|---|
| 398 | };
|
|---|
| 399 |
|
|---|
| 400 | struct key_info {
|
|---|
| 401 | std::wstring path;
|
|---|
| 402 | std::wstring key_name;
|
|---|
| 403 | std::wstring parent;
|
|---|
| 404 |
|
|---|
| 405 | boost::shared_ptr<key_interface> key;
|
|---|
| 406 | description_container description;
|
|---|
| 407 |
|
|---|
| 408 | key_info(std::wstring path_, std::wstring key_name_, boost::shared_ptr<key_interface> key, description_container description_)
|
|---|
| 409 | : path(path_)
|
|---|
| 410 | , key_name(key_name_)
|
|---|
| 411 | , key(key)
|
|---|
| 412 | , description(description_)
|
|---|
| 413 | {}
|
|---|
| 414 | key_info(const key_info& obj) : path(obj.path), key_name(obj.key_name), key(obj.key), description(obj.description), parent(obj.parent) {}
|
|---|
| 415 | virtual key_info& operator=(const key_info& obj) {
|
|---|
| 416 | path = obj.path;
|
|---|
| 417 | key_name = obj.key_name;
|
|---|
| 418 | key = obj.key;
|
|---|
| 419 | description = obj.description;
|
|---|
| 420 | parent = obj.parent;
|
|---|
| 421 | return *this;
|
|---|
| 422 | }
|
|---|
| 423 | void set_parent(std::wstring parent_) {
|
|---|
| 424 | parent = parent_;
|
|---|
| 425 | }
|
|---|
| 426 | bool has_parent() const {
|
|---|
| 427 | return !parent.empty();
|
|---|
| 428 | }
|
|---|
| 429 | std::wstring get_parent() const {
|
|---|
| 430 | return parent;
|
|---|
| 431 | }
|
|---|
| 432 | };
|
|---|
| 433 | struct path_info {
|
|---|
| 434 | std::wstring path_name;
|
|---|
| 435 | description_container description;
|
|---|
| 436 | boost::shared_ptr<path_interface> path;
|
|---|
| 437 |
|
|---|
| 438 | path_info(std::wstring path_name, description_container description_) : path_name(path_name), description(description_) {}
|
|---|
| 439 | path_info(std::wstring path_name, boost::shared_ptr<path_interface> path, description_container description_) : path_name(path_name), path(path), description(description_) {}
|
|---|
| 440 |
|
|---|
| 441 | path_info(const path_info& obj) : path_name(obj.path_name), description(obj.description), path(obj.path) {}
|
|---|
| 442 | virtual path_info& operator=(const path_info& obj) {
|
|---|
| 443 | path_name = obj.path_name;
|
|---|
| 444 | path = obj.path;
|
|---|
| 445 | description = obj.description;
|
|---|
| 446 | return *this;
|
|---|
| 447 | }
|
|---|
| 448 |
|
|---|
| 449 | };
|
|---|
| 450 |
|
|---|
| 451 | class settings_registry;
|
|---|
| 452 | class settings_paths_easy_init {
|
|---|
| 453 | public:
|
|---|
| 454 | settings_paths_easy_init(settings_registry* owner) : owner(owner) {}
|
|---|
| 455 | settings_paths_easy_init(std::wstring path, settings_registry* owner) : path_(path), owner(owner) {}
|
|---|
| 456 |
|
|---|
| 457 | settings_paths_easy_init& operator()(boost::shared_ptr<path_interface> value, std::wstring title, std::wstring description) {
|
|---|
| 458 | boost::shared_ptr<path_info> d(new path_info(path_, value, description_container(title, description)));
|
|---|
| 459 | add(d);
|
|---|
| 460 | return *this;
|
|---|
| 461 | }
|
|---|
| 462 | settings_paths_easy_init& operator()(std::wstring title, std::wstring description) {
|
|---|
| 463 | boost::shared_ptr<path_info> d(new path_info(path_, description_container(title, description)));
|
|---|
| 464 | add(d);
|
|---|
| 465 | return *this;
|
|---|
| 466 | }
|
|---|
| 467 | settings_paths_easy_init& operator()(std::wstring path, std::wstring title, std::wstring description) {
|
|---|
| 468 | if (!path_.empty())
|
|---|
| 469 | path = path_ + _T("/") + path;
|
|---|
| 470 | boost::shared_ptr<path_info> d(new path_info(path, description_container(title, description)));
|
|---|
| 471 | add(d);
|
|---|
| 472 | return *this;
|
|---|
| 473 | }
|
|---|
| 474 | settings_paths_easy_init& operator()(std::wstring path, boost::shared_ptr<path_interface> value, std::wstring title, std::wstring description) {
|
|---|
| 475 | if (!path_.empty())
|
|---|
| 476 | path = path_ + _T("/") + path;
|
|---|
| 477 | boost::shared_ptr<path_info> d(new path_info(path, value, description_container(title, description)));
|
|---|
| 478 | add(d);
|
|---|
| 479 | return *this;
|
|---|
| 480 | }
|
|---|
| 481 |
|
|---|
| 482 | void add(boost::shared_ptr<path_info> d);
|
|---|
| 483 |
|
|---|
| 484 | private:
|
|---|
| 485 | settings_registry* owner;
|
|---|
| 486 | std::wstring path_;
|
|---|
| 487 | };
|
|---|
| 488 |
|
|---|
| 489 | class settings_keys_easy_init {
|
|---|
| 490 | public:
|
|---|
| 491 | settings_keys_easy_init(settings_registry* owner_) : owner(owner_) {}
|
|---|
| 492 | settings_keys_easy_init(std::wstring path, settings_registry* owner_) : owner(owner_), path_(path) {}
|
|---|
| 493 | settings_keys_easy_init(std::wstring path, std::wstring parent, settings_registry* owner_) : owner(owner_), path_(path), parent_(parent) {}
|
|---|
| 494 |
|
|---|
| 495 | settings_keys_easy_init& operator()(std::wstring path, std::wstring key_name, boost::shared_ptr<key_interface> value, std::wstring title, std::wstring description, bool advanced = false) {
|
|---|
| 496 | boost::shared_ptr<key_info> d(new key_info(path, key_name, value, description_container(title, description, advanced)));
|
|---|
| 497 | if (!parent_.empty())
|
|---|
| 498 | d->set_parent(parent_);
|
|---|
| 499 | add(d);
|
|---|
| 500 | return *this;
|
|---|
| 501 | }
|
|---|
| 502 |
|
|---|
| 503 | settings_keys_easy_init& operator()(std::wstring key_name, boost::shared_ptr<key_interface> value, std::wstring title, std::wstring description, bool advanced = false) {
|
|---|
| 504 | boost::shared_ptr<key_info> d(new key_info(path_, key_name, value, description_container(title, description, advanced)));
|
|---|
| 505 | if (!parent_.empty())
|
|---|
| 506 | d->set_parent(parent_);
|
|---|
| 507 | add(d);
|
|---|
| 508 | return *this;
|
|---|
| 509 | }
|
|---|
| 510 |
|
|---|
| 511 | void add(boost::shared_ptr<key_info> d);
|
|---|
| 512 |
|
|---|
| 513 | private:
|
|---|
| 514 | settings_registry* owner;
|
|---|
| 515 | std::wstring path_;
|
|---|
| 516 | std::wstring parent_;
|
|---|
| 517 | };
|
|---|
| 518 |
|
|---|
| 519 |
|
|---|
| 520 | class path_extension {
|
|---|
| 521 | public:
|
|---|
| 522 | path_extension(settings_registry * owner, std::wstring path) : owner_(owner), path_(path) {}
|
|---|
| 523 |
|
|---|
| 524 | settings_keys_easy_init add_key_to_path(std::wstring path) {
|
|---|
| 525 | return settings_keys_easy_init(get_path(path), owner_);
|
|---|
| 526 | }
|
|---|
| 527 | settings_keys_easy_init add_key() {
|
|---|
| 528 | return settings_keys_easy_init(path_, owner_);
|
|---|
| 529 | }
|
|---|
| 530 | settings_paths_easy_init add_path(std::wstring path = _T("")) {
|
|---|
| 531 | return settings_paths_easy_init(get_path(path), owner_);
|
|---|
| 532 | }
|
|---|
| 533 | inline std::wstring get_path(std::wstring path) {
|
|---|
| 534 | if (!path.empty())
|
|---|
| 535 | return path_ + _T("/") + path;
|
|---|
| 536 | return path_;
|
|---|
| 537 | }
|
|---|
| 538 |
|
|---|
| 539 | private:
|
|---|
| 540 | std::wstring path_;
|
|---|
| 541 | settings_registry * owner_;
|
|---|
| 542 | };
|
|---|
| 543 | class alias_extension {
|
|---|
| 544 | public:
|
|---|
| 545 | alias_extension(settings_registry * owner, std::wstring alias) : owner_(owner), alias_(alias) {}
|
|---|
| 546 | alias_extension(const alias_extension &other) : owner_(other.owner_), alias_(other.alias_), parent_(other.parent_) {}
|
|---|
| 547 | alias_extension& operator = (const alias_extension& other) {
|
|---|
| 548 | owner_ = other.owner_;
|
|---|
| 549 | alias_ = other.alias_;
|
|---|
| 550 | parent_ = other.parent_;
|
|---|
| 551 | return *this;
|
|---|
| 552 | }
|
|---|
| 553 |
|
|---|
| 554 | settings_keys_easy_init add_key_to_path(std::wstring path) {
|
|---|
| 555 | return settings_keys_easy_init(get_path(path), parent_, owner_);
|
|---|
| 556 | }
|
|---|
| 557 | settings_paths_easy_init add_path(std::wstring path) {
|
|---|
| 558 | return settings_paths_easy_init(get_path(path), owner_);
|
|---|
| 559 | }
|
|---|
| 560 | inline std::wstring get_path(std::wstring path = _T("")) {
|
|---|
| 561 | if (path.empty())
|
|---|
| 562 | return _T("/") + alias_;
|
|---|
| 563 | return path + _T("/") + alias_;
|
|---|
| 564 | }
|
|---|
| 565 |
|
|---|
| 566 |
|
|---|
| 567 | settings_keys_easy_init add_key_to_settings(std::wstring path = _T("")) {
|
|---|
| 568 | return settings_keys_easy_init(get_settings_path(path), parent_, owner_);
|
|---|
| 569 | }
|
|---|
| 570 | settings_paths_easy_init add_path_to_settings(std::wstring path = _T("")) {
|
|---|
| 571 | return settings_paths_easy_init(get_settings_path(path), owner_);
|
|---|
| 572 | }
|
|---|
| 573 | inline std::wstring get_settings_path(std::wstring path) {
|
|---|
| 574 | if (path.empty())
|
|---|
| 575 | return _T("/settings/") + alias_;
|
|---|
| 576 | return _T("/settings/") + alias_ + _T("/") + path;
|
|---|
| 577 | }
|
|---|
| 578 |
|
|---|
| 579 | alias_extension add_parent(std::wstring parent_path) {
|
|---|
| 580 | set_parent_path(parent_path);
|
|---|
| 581 | return *this;
|
|---|
| 582 | }
|
|---|
| 583 |
|
|---|
| 584 |
|
|---|
| 585 | static std::wstring get_alias(std::wstring cur, std::wstring def) {
|
|---|
| 586 | if (cur.empty())
|
|---|
| 587 | return def;
|
|---|
| 588 | else
|
|---|
| 589 | return cur;
|
|---|
| 590 | }
|
|---|
| 591 | static std::wstring get_alias(std::wstring prefix, std::wstring cur, std::wstring def) {
|
|---|
| 592 | if (!prefix.empty())
|
|---|
| 593 | prefix += _T("/");
|
|---|
| 594 | if (cur.empty())
|
|---|
| 595 | return prefix + def;
|
|---|
| 596 | else
|
|---|
| 597 | return prefix + cur;
|
|---|
| 598 | }
|
|---|
| 599 | void set_alias(std::wstring cur, std::wstring def) {
|
|---|
| 600 | alias_ = get_alias(cur, def);
|
|---|
| 601 | }
|
|---|
| 602 | void set_alias(std::wstring prefix, std::wstring cur, std::wstring def) {
|
|---|
| 603 | alias_ = get_alias(prefix, cur, def);
|
|---|
| 604 | }
|
|---|
| 605 | void set_parent_path(std::wstring parent) {
|
|---|
| 606 | parent_ = parent;
|
|---|
| 607 | }
|
|---|
| 608 |
|
|---|
| 609 | private:
|
|---|
| 610 | std::wstring alias_;
|
|---|
| 611 | settings_registry * owner_;
|
|---|
| 612 | std::wstring parent_;
|
|---|
| 613 | };
|
|---|
| 614 |
|
|---|
| 615 | class settings_registry {
|
|---|
| 616 | typedef std::list<boost::shared_ptr<key_info> > key_list;
|
|---|
| 617 | typedef std::list<boost::shared_ptr<path_info> > path_list;
|
|---|
| 618 | key_list keys_;
|
|---|
| 619 | path_list paths_;
|
|---|
| 620 | settings_impl_interface_ptr core_;
|
|---|
| 621 | std::wstring alias_;
|
|---|
| 622 | public:
|
|---|
| 623 | settings_registry(settings_impl_interface_ptr core) : core_(core) {}
|
|---|
| 624 | void add(boost::shared_ptr<key_info> info) {
|
|---|
| 625 | keys_.push_back(info);
|
|---|
| 626 | }
|
|---|
| 627 | void add(boost::shared_ptr<path_info> info) {
|
|---|
| 628 | paths_.push_back(info);
|
|---|
| 629 | }
|
|---|
| 630 |
|
|---|
| 631 | settings_keys_easy_init add_key() {
|
|---|
| 632 | return settings_keys_easy_init(this);
|
|---|
| 633 | }
|
|---|
| 634 | settings_keys_easy_init add_key_to_path(std::wstring path) {
|
|---|
| 635 | return settings_keys_easy_init(path, this);
|
|---|
| 636 | }
|
|---|
| 637 | settings_keys_easy_init add_key_to_settings(std::wstring path) {
|
|---|
| 638 | return settings_keys_easy_init(_T("/settings/") + path, this);
|
|---|
| 639 | }
|
|---|
| 640 | settings_paths_easy_init add_path() {
|
|---|
| 641 | return settings_paths_easy_init(this);
|
|---|
| 642 | }
|
|---|
| 643 | settings_paths_easy_init add_path_to_settings() {
|
|---|
| 644 | return settings_paths_easy_init(_T("/settings"), this);
|
|---|
| 645 | }
|
|---|
| 646 |
|
|---|
| 647 | void set_alias(std::wstring cur, std::wstring def) {
|
|---|
| 648 | alias_ = alias_extension::get_alias(cur, def);
|
|---|
| 649 | }
|
|---|
| 650 | void set_alias(std::wstring prefix, std::wstring cur, std::wstring def) {
|
|---|
| 651 | alias_ = alias_extension::get_alias(prefix, cur, def);
|
|---|
| 652 | }
|
|---|
| 653 | void set_alias(std::wstring alias) {
|
|---|
| 654 | alias_ = alias;
|
|---|
| 655 | }
|
|---|
| 656 | alias_extension alias() {
|
|---|
| 657 | return alias_extension(this, alias_);
|
|---|
| 658 | }
|
|---|
| 659 | alias_extension alias(std::wstring alias) {
|
|---|
| 660 | return alias_extension(this, alias);
|
|---|
| 661 | }
|
|---|
| 662 | alias_extension alias(std::wstring cur, std::wstring def) {
|
|---|
| 663 | return alias_extension(this, alias_extension::get_alias(cur, def));
|
|---|
| 664 | }
|
|---|
| 665 | alias_extension alias(std::wstring prefix, std::wstring cur, std::wstring def) {
|
|---|
| 666 | return alias_extension(this, alias_extension::get_alias(prefix, cur, def));
|
|---|
| 667 | }
|
|---|
| 668 |
|
|---|
| 669 | path_extension path(std::wstring path) {
|
|---|
| 670 | return path_extension(this, path);
|
|---|
| 671 | }
|
|---|
| 672 |
|
|---|
| 673 |
|
|---|
| 674 | void register_all() {
|
|---|
| 675 | BOOST_FOREACH(key_list::value_type v, keys_) {
|
|---|
| 676 | if (v->key) {
|
|---|
| 677 | //std::wcout << _T("Setting: ") << v->key_name << _T(" ===> ") << v->parent << std::endl;
|
|---|
| 678 | std::wstring desc = v->description.description;
|
|---|
| 679 | if (v->has_parent()) {
|
|---|
| 680 | desc += _T(" Parent element can be found under: ") + v->parent;
|
|---|
| 681 | core_->register_key(v->parent, v->key_name, v->key->get_type(), v->description.title, desc, v->key->get_default_as_string(), v->description.advanced);
|
|---|
| 682 | }
|
|---|
| 683 | core_->register_key(v->path, v->key_name, v->key->get_type(), v->description.title, desc, v->key->get_default_as_string(), v->description.advanced);
|
|---|
| 684 | }
|
|---|
| 685 | }
|
|---|
| 686 | BOOST_FOREACH(path_list::value_type v, paths_) {
|
|---|
| 687 | core_->register_path(v->path_name, v->description.title, v->description.description, v->description.advanced);
|
|---|
| 688 | }
|
|---|
| 689 | }
|
|---|
| 690 | void clear() {
|
|---|
| 691 | keys_.clear();
|
|---|
| 692 | paths_.clear();
|
|---|
| 693 | }
|
|---|
| 694 |
|
|---|
| 695 | void notify() {
|
|---|
| 696 | BOOST_FOREACH(key_list::value_type v, keys_) {
|
|---|
| 697 | try {
|
|---|
| 698 | if (v->key) {
|
|---|
| 699 | if (v->has_parent())
|
|---|
| 700 | v->key->notify(core_, v->parent, v->path, v->key_name);
|
|---|
| 701 | else
|
|---|
| 702 | v->key->notify(core_, v->path, v->key_name);
|
|---|
| 703 | }
|
|---|
| 704 | } catch (const std::exception &e) {
|
|---|
| 705 | core_->err(__FILE__, __LINE__, _T("Failed to notify ") + v->key_name + _T(": ") + utf8::cvt<std::wstring>(e.what()));
|
|---|
| 706 | } catch (...) {
|
|---|
| 707 | core_->err(__FILE__, __LINE__, _T("Failed to notify: ") + v->key_name);
|
|---|
| 708 | }
|
|---|
| 709 | }
|
|---|
| 710 | BOOST_FOREACH(path_list::value_type v, paths_) {
|
|---|
| 711 | try {
|
|---|
| 712 | if (v->path)
|
|---|
| 713 | v->path->notify(core_, v->path_name);
|
|---|
| 714 | } catch (const std::exception &e) {
|
|---|
| 715 | core_->err(__FILE__, __LINE__, _T("Failed to notify ") + v->path_name + _T(": ") + utf8::cvt<std::wstring>(e.what()));
|
|---|
| 716 | } catch (...) {
|
|---|
| 717 | core_->err(__FILE__, __LINE__, _T("Failed to notify: ") + v->path_name);
|
|---|
| 718 | }
|
|---|
| 719 | }
|
|---|
| 720 |
|
|---|
| 721 | }
|
|---|
| 722 | };
|
|---|
| 723 | }
|
|---|
| 724 | } |
|---|