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