source: nscp/include/settings/client/settings_client.hpp @ 465866c

0.4.10.4.2
Last change on this file since 465866c was 465866c, checked in by Michael Medin <michael@…>, 13 months ago

2012-06-05 MickeM

  • Tweaked all servers to use the new internals and added first testcase for NSCP socket

2012-05-24 MickeM

  • Reworked real time event log support to be a lot more flexible You can now specify all options on a "filter" level.
  • WARNING* Old syntax NOT supported (and will not upgrade) but hopefully not to many will be affected.
  • Added support for ipv6 allowed hosts validation

2012-05-21 MickeM

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