1 #ifndef _library__settingvar__hpp__included__
2 #define _library__settingvar__hpp__included__
19 threads::rlock
& get_setting_lock();
22 * A settings listener.
29 virtual ~listener() throw();
31 * Listen for setting changing value.
33 virtual void on_setting_change(group
& _group
, const base
& val
) = 0;
37 * A set of setting variables.
43 * Set add/drop listener.
55 virtual void create(set
& s
, const std::string
& name
, superbase
& svar
) = 0;
57 * Deleted item from set.
59 virtual void destroy(set
& s
, const std::string
& name
) = 0;
61 * Destroyed the entiere set.
63 virtual void kill(set
& s
) = 0;
74 * Register a supervariable.
76 void do_register(const std::string
& name
, superbase
& info
);
78 * Unregister a supervariable.
80 void do_unregister(const std::string
& name
, superbase
& info
);
82 * Add a callback on new supervariable.
84 void add_callback(listener
& listener
);
86 * Drop a callback on new supervariable.
88 void drop_callback(listener
& listener
);
94 * Group of setting variables.
110 std::set
<std::string
> get_settings_set();
114 base
& operator[](const std::string
& name
);
118 void add_listener(struct listener
& _listener
);
122 void remove_listener(struct listener
& _listener
);
124 * Register a setting.
126 void do_register(const std::string
& name
, base
& _setting
);
128 * Unregister a setting.
130 void do_unregister(const std::string
& name
, base
& _setting
);
134 void fire_listener(base
& var
) throw();
136 * Add a set of settings.
138 void add_set(set
& s
);
140 * Remove a set of settings.
142 void drop_set(set
& s
);
147 class xlistener
: public set::listener
150 xlistener(group
& _grp
);
152 void create(set
& s
, const std::string
& name
, superbase
& sb
);
153 void destroy(set
& s
, const std::string
& name
);
161 * Write-trough value cache.
171 * Enumerate contents.
173 * Note: This reads cached values in perference to actual values.
175 std::map
<std::string
, std::string
> get_all();
177 * Enumerate valid keys.
179 * Returns: The set of actually valid keys.
181 std::set
<std::string
> get_keys();
185 * Parameter name: Name of the setting.
186 * Parameter value: New value for the setting.
187 * Parameter allow_invalid: Cache value if invalid, instead of throwing.
188 * Throws std::runtime_error: Failed to set the setting and invalid values not allowed.
190 * Note: If setting has cached value and setting it succeeds, the cached value is cleared.
192 void set(const std::string
& name
, const std::string
& value
, bool allow_invalid
= false);
196 * Parameter name: Name of the setting.
197 * Return: Actual value of the setting.
198 * Throws std::runtime_error: Setting doesn't exist.
200 std::string
get(const std::string
& name
);
202 * Get descriptor for.
204 const description
& get_description(const std::string
& name
);
206 * Get human-readable name.
208 * Parameter name: Name of the setting.
209 * Return: Human-readable name of the setting.
210 * Throws std::runtime_error: Setting doesn't exist.
212 std::string
get_hname(const std::string
& name
);
215 std::map
<std::string
, std::string
> badcache
;
223 enumeration(std::initializer_list
<const char*> v
)
227 values
[bound
= x
++] = i
;
230 std::string
get(unsigned val
) { return values
.count(val
) ? values
[val
] : ""; }
231 unsigned max_val() { return bound
; }
233 std::map
<unsigned, std::string
> values
;
238 * Description of setting.
253 enumeration
* _enumeration
;
257 * Get the description.
259 template<class T
> static class description
& description_get(T dummy
);
270 void _superbase(set
& _s
, const std::string
& iname
);
274 virtual ~superbase() throw();
278 virtual base
* make(group
& grp
) = 0;
297 base(group
& _group
, const std::string
& iname
, const std::string
& hname
, bool dynamic
);
301 virtual ~base() throw();
305 virtual void str(const std::string
& val
) = 0;
309 virtual std::string
str() const = 0;
313 const std::string
& get_iname() const throw() { return iname
; }
314 const std::string
& get_hname() const throw() { return hname
; }
316 * Get setting description.
318 virtual const description
& get_description() const throw() = 0;
320 * Notify group death.
325 base
& operator=(const base
&);
335 template<class model
> class variable
: public base
337 typedef typename
model::valtype_t valtype_t
;
338 variable(const variable
<model
>&);
339 variable
<model
>& operator=(const variable
<model
>&);
344 variable(group
& sgroup
, const std::string
& iname
, const std::string
& hname
,
345 valtype_t defaultvalue
, bool dynamic
= false)
346 : base(sgroup
, iname
, hname
, dynamic
)
348 value
= defaultvalue
;
353 virtual ~variable() throw()
359 void str(const std::string
& val
)
362 threads::arlock
h(get_setting_lock());
363 value
= model::read(val
);
365 sgroup
->fire_listener(*this);
370 std::string
str() const
372 threads::arlock
h(get_setting_lock());
373 return model::write(value
);
378 void set(valtype_t _value
)
381 threads::arlock
h(get_setting_lock());
382 if(!model::valid(value
))
383 throw std::runtime_error("Invalid value");
386 sgroup
->fire_listener(*this);
391 valtype_t
get() const
393 threads::arlock
h(get_setting_lock());
394 return model::transform(value
);
399 operator valtype_t() const
404 * Get setting description.
406 const description
& get_description() const throw()
408 return description_get(dummy
);
416 * Supervariable with model.
418 template<class model
> class supervariable
: public superbase
420 typedef typename
model::valtype_t valtype_t
;
421 supervariable(const supervariable
<model
>&);
422 supervariable
<model
>& operator=(const supervariable
<model
>&);
427 supervariable(set
& _s
, const std::string
& _iname
, const std::string
& _hname
, valtype_t _defaultvalue
)
432 defaultvalue
= _defaultvalue
;
433 _superbase(_s
, iname
);
438 ~supervariable() throw()
444 base
* make(group
& grp
)
446 return new variable
<model
>(grp
, iname
, hname
, defaultvalue
, true);
449 * Read value in instance.
451 valtype_t
operator()(group
& grp
)
453 base
* b
= &grp
[iname
];
454 variable
<model
>* m
= dynamic_cast<variable
<model
>*>(b
);
456 throw std::runtime_error("No such setting in target group");
460 * Write value in instance.
462 void operator()(group
& grp
, valtype_t val
)
464 base
* b
= &grp
[iname
];
465 variable
<model
>* m
= dynamic_cast<variable
<model
>*>(b
);
467 throw std::runtime_error("No such setting in target group");
474 valtype_t defaultvalue
;
482 static const char* enable
;
483 static const char* disable
;
489 template<typename values
> struct model_bool
491 typedef bool valtype_t
;
492 static bool valid(bool val
) { return true; /* Any boolean is valid boolean. */ }
493 static bool read(const std::string
& val
)
495 int x
= string_to_bool(val
);
497 throw std::runtime_error("Invalid boolean value");
500 static std::string
write(bool val
)
502 return val
? values::enable
: values::disable
;
504 static bool transform(bool val
) { return val
; }
507 template<typename values
> description
& description_get(
508 model_bool
<values
> X
)
510 static description x
;
511 static bool init
= false;
513 x
.type
= description::T_BOOLEAN
;
522 template<int32_t minimum
, int32_t maximum
> struct model_int
524 typedef int32_t valtype_t
;
525 static bool valid(int32_t val
) { return (val
>= minimum
&& val
<= maximum
); }
526 static int32_t read(const std::string
& val
)
528 int x
= parse_value
<int32_t>(val
);
529 if(x
< minimum
|| x
> maximum
)
530 (stringfmt() << "Value out of range (" << minimum
<< " to " << maximum
<< ")").throwex();
533 static std::string
write(int32_t val
)
535 return (stringfmt() << val
).str();
537 static int transform(int val
) { return val
; }
540 template<int32_t m
, int32_t M
> description
& description_get(model_int
<m
, M
> X
)
542 static description x
;
543 static bool init
= false;
545 x
.type
= description::T_NUMERIC
;
558 typedef std::string valtype_t
;
559 static bool valid(std::string val
) { return true; /* Any boolean is valid boolean. */ }
560 static std::string
read(const std::string
& val
)
564 static std::string
write(std::string val
)
568 static std::string
transform(std::string val
)
570 return (val
!= "") ? val
: ".";
574 template<> description
& description_get(model_path X
)
576 static description x
;
577 static bool init
= false;
579 x
.type
= description::T_PATH
;
588 template<enumeration
* e
> struct model_enumerated
590 typedef unsigned valtype_t
;
591 static bool valid(unsigned val
) { return (val
<= e
->max_val()); }
592 static unsigned read(const std::string
& val
)
594 for(unsigned i
= 0; i
<= e
->max_val(); i
++)
597 unsigned x
= parse_value
<unsigned>(val
);
599 (stringfmt() << "Value out of range (0 to " << e
->max_val() << ")").throwex();
602 static std::string
write(unsigned val
)
606 static int transform(int val
) { return val
; }
609 template<enumeration
* e
> description
& description_get(model_enumerated
<e
> X
)
611 static description x
;
612 static bool init
= false;
614 x
.type
= description::T_ENUMERATION
;