1 #ifndef _library__settingvar__hpp__included__
2 #define _library__settingvar__hpp__included__
7 #include "threadtypes.hpp"
11 class setting_var_base
;
12 class setting_var_group
;
13 class setting_var_description
;
16 * A settings listener.
18 struct setting_var_listener
23 virtual ~setting_var_listener() throw();
25 * Listen for setting changing value.
27 virtual void on_setting_change(setting_var_group
& group
, const setting_var_base
& val
) = 0;
31 * Group of setting variables.
33 class setting_var_group
39 setting_var_group() throw(std::bad_alloc
);
43 ~setting_var_group() throw();
47 std::set
<std::string
> get_settings_set() throw(std::bad_alloc
);
51 setting_var_base
& operator[](const std::string
& name
);
55 void add_listener(struct setting_var_listener
& listener
) throw(std::bad_alloc
);
59 void remove_listener(struct setting_var_listener
& listener
) throw(std::bad_alloc
);
63 void do_register(const std::string
& name
, setting_var_base
& _setting
) throw(std::bad_alloc
);
65 * Unregister a setting.
67 void do_unregister(const std::string
& name
) throw(std::bad_alloc
);
71 void fire_listener(setting_var_base
& var
) throw();
73 std::map
<std::string
, class setting_var_base
*> settings
;
74 std::set
<struct setting_var_listener
*> listeners
;
79 * Write-trough value cache.
81 class setting_var_cache
87 setting_var_cache(setting_var_group
& grp
);
91 * Note: This reads cached values in perference to actual values.
93 std::map
<std::string
, std::string
> get_all();
95 * Enumerate valid keys.
97 * Returns: The set of actually valid keys.
99 std::set
<std::string
> get_keys();
103 * Parameter name: Name of the setting.
104 * Parameter value: New value for the setting.
105 * Parameter allow_invalid: Cache value if invalid, instead of throwing.
106 * Throws std::runtime_error: Failed to set the setting and invalid values not allowed.
108 * Note: If setting has cached value and setting it succeeds, the cached value is cleared.
110 void set(const std::string
& name
, const std::string
& value
, bool allow_invalid
= false) throw(std::bad_alloc
,
115 * Parameter name: Name of the setting.
116 * Return: Actual value of the setting.
117 * Throws std::runtime_error: Setting doesn't exist.
119 std::string
get(const std::string
& name
) throw(std::bad_alloc
, std::runtime_error
);
121 * Get descriptor for.
123 const setting_var_description
& get_description(const std::string
& name
) throw(std::bad_alloc
,
126 setting_var_group
& grp
;
128 std::map
<std::string
, std::string
> badcache
;
134 struct setting_enumeration
136 setting_enumeration(std::initializer_list
<const char*> v
)
140 values
[bound
= x
++] = i
;
143 std::string
get(unsigned val
) { return values
.count(val
) ? values
[val
] : ""; }
144 unsigned max_val() { return bound
; }
146 std::map
<unsigned, std::string
> values
;
151 * Description of setting.
153 struct setting_var_description
166 setting_enumeration
* enumeration
;
170 * Get the description.
172 template<class T
> static class setting_var_description
& setting_var_description_get(T dummy
);
177 class setting_var_base
183 setting_var_base(setting_var_group
& group
, const std::string
& iname
, const std::string
& hname
)
184 throw(std::bad_alloc
);
188 virtual ~setting_var_base() throw();
192 virtual void str(const std::string
& val
) throw(std::runtime_error
, std::bad_alloc
) = 0;
196 virtual std::string
str() const throw(std::runtime_error
, std::bad_alloc
) = 0;
200 const std::string
& get_iname() const throw() { return iname
; }
201 const std::string
& get_hname() const throw() { return hname
; }
203 * Get setting description.
205 virtual const setting_var_description
& get_description() const throw() = 0;
207 setting_var_base(const setting_var_base
&);
208 setting_var_base
& operator=(const setting_var_base
&);
209 setting_var_group
& group
;
212 mutable mutex_class lock
;
218 template<class model
> class setting_var
: public setting_var_base
220 typedef typename
model::valtype_t valtype_t
;
221 setting_var(const setting_var
<model
>&);
222 setting_var
<model
>& operator=(const setting_var
<model
>&);
227 setting_var(setting_var_group
& group
, const std::string
& iname
, const std::string
& hname
,
228 valtype_t defaultvalue
)
229 : setting_var_base(group
, iname
, hname
)
231 value
= defaultvalue
;
236 virtual ~setting_var() throw()
242 void str(const std::string
& val
) throw(std::runtime_error
, std::bad_alloc
)
245 umutex_class
h(lock
);
246 value
= model::read(val
);
248 group
.fire_listener(*this);
253 std::string
str() const throw(std::runtime_error
, std::bad_alloc
)
255 umutex_class
h(lock
);
256 return model::write(value
);
261 void set(valtype_t _value
) throw(std::runtime_error
, std::bad_alloc
)
264 umutex_class
h(lock
);
265 if(!model::valid(value
))
266 throw std::runtime_error("Invalid value");
269 group
.fire_listener(*this);
274 valtype_t
get() throw(std::bad_alloc
)
276 umutex_class
h(lock
);
277 return model::transform(value
);
287 * Get setting description.
289 const setting_var_description
& get_description() const throw()
291 return setting_var_description_get(dummy
);
301 struct setting_yes_no
303 static const char* enable
;
304 static const char* disable
;
310 template<typename values
> struct setting_var_model_bool
312 typedef bool valtype_t
;
313 static bool valid(bool val
) { return true; /* Any boolean is valid boolean. */ }
314 static bool read(const std::string
& val
)
316 int x
= string_to_bool(val
);
318 throw std::runtime_error("Invalid boolean value");
321 static std::string
write(bool val
)
323 return val
? values::enable
: values::disable
;
325 static bool transform(bool val
) { return val
; }
328 template<typename values
> setting_var_description
& setting_var_description_get(
329 setting_var_model_bool
<values
> X
)
331 static setting_var_description x
;
332 static bool init
= false;
334 x
.type
= setting_var_description::T_BOOLEAN
;
343 template<int32_t minimum
, int32_t maximum
> struct setting_var_model_int
345 typedef int32_t valtype_t
;
346 static bool valid(int32_t val
) { return (val
>= minimum
&& val
<= maximum
); }
347 static int32_t read(const std::string
& val
)
349 int x
= parse_value
<int32_t>(val
);
350 if(x
< minimum
|| x
> maximum
)
351 (stringfmt() << "Value out of range (" << minimum
<< " to " << maximum
<< ")").throwex();
354 static std::string
write(int32_t val
)
356 return (stringfmt() << val
).str();
358 static int transform(int val
) { return val
; }
361 template<int32_t m
, int32_t M
> setting_var_description
& setting_var_description_get(setting_var_model_int
<m
, M
> X
)
363 static setting_var_description x
;
364 static bool init
= false;
366 x
.type
= setting_var_description::T_NUMERIC
;
377 struct setting_var_model_path
379 typedef std::string valtype_t
;
380 static bool valid(std::string val
) { return true; /* Any boolean is valid boolean. */ }
381 static std::string
read(const std::string
& val
)
385 static std::string
write(std::string val
)
389 static std::string
transform(std::string val
)
391 return (val
!= "") ? val
: ".";
395 template<> setting_var_description
& setting_var_description_get(setting_var_model_path X
)
397 static setting_var_description x
;
398 static bool init
= false;
400 x
.type
= setting_var_description::T_PATH
;
409 template<setting_enumeration
* e
> struct setting_var_model_enumerated
411 typedef unsigned valtype_t
;
412 static bool valid(unsigned val
) { return (val
<= e
->max_val()); }
413 static unsigned read(const std::string
& val
)
415 for(unsigned i
= 0; i
<= e
->max_val(); i
++)
418 unsigned x
= parse_value
<unsigned>(val
);
420 (stringfmt() << "Value out of range (0 to " << e
->max_val() << ")").throwex();
423 static std::string
write(unsigned val
)
427 static int transform(int val
) { return val
; }
430 template<setting_enumeration
* e
> setting_var_description
& setting_var_description_get(
431 setting_var_model_enumerated
<e
> X
)
433 static setting_var_description x
;
434 static bool init
= false;
436 x
.type
= setting_var_description::T_ENUMERATION
;