1 #include "globalwrap.hpp"
2 #include "register-queue.hpp"
3 #include "settings.hpp"
13 struct pending_registration
20 typedef register_queue
<setting_group
, setting
> regqueue_t
;
23 setting_listener::~setting_listener() throw()
27 setting_group::setting_group() throw(std::bad_alloc
)
29 regqueue_t::do_ready(*this, true);
32 setting_group::~setting_group() throw()
34 regqueue_t::do_ready(*this, false);
37 setting
* setting_group::get_by_name(const std::string
& name
)
40 if(!settings
.count(name
))
41 throw std::runtime_error("No such setting '" + name
+ "'");
42 return settings
[name
];
45 void setting_group::set(const std::string
& _setting
, const std::string
& value
) throw(std::bad_alloc
,
50 tochange
= get_by_name(_setting
);
53 invalid_values
[_setting
] = value
;
58 setting::lock_holder
lck(tochange
);
60 invalid_values
.erase(_setting
);
62 std::set
<setting_listener
*> l
;
65 for(auto i
: listeners
)
69 i
->changed(*this, _setting
, value
);
70 } catch(std::bad_alloc
& e
) {
72 } catch(std::exception
& e
) {
74 invalid_values
[_setting
] = value
;
75 throw std::runtime_error("Can't set setting '" + _setting
+ "': " + e
.what());
79 bool setting_group::blankable(const std::string
& _setting
) throw(std::bad_alloc
, std::runtime_error
)
81 setting
* tochange
= get_by_name(_setting
);
84 setting::lock_holder
lck(tochange
);
85 return tochange
->blank(false);
92 void setting_group::blank(const std::string
& _setting
) throw(std::bad_alloc
, std::runtime_error
)
94 setting
* tochange
= get_by_name(_setting
);
97 setting::lock_holder
lck(tochange
);
98 if(!tochange
->blank(true))
99 throw std::runtime_error("This setting can't be cleared");
100 invalid_values
.erase(_setting
);
102 std::set
<setting_listener
*> l
;
104 umutex_class
h(lock
);
105 for(auto i
: listeners
)
109 i
->blanked(*this, _setting
);
110 } catch(std::bad_alloc
& e
) {
112 } catch(std::exception
& e
) {
113 throw std::runtime_error("Can't clear setting '" + _setting
+ "': " + e
.what());
117 std::string
setting_group::get(const std::string
& _setting
) throw(std::bad_alloc
, std::runtime_error
)
119 setting
* tochange
= get_by_name(_setting
);
121 setting::lock_holder
lck(tochange
);
122 return tochange
->get();
126 bool setting_group::is_set(const std::string
& _setting
) throw(std::bad_alloc
, std::runtime_error
)
128 setting
* tochange
= get_by_name(_setting
);
130 setting::lock_holder
lck(tochange
);
131 return tochange
->is_set();
135 std::set
<std::string
> setting_group::get_settings_set() throw(std::bad_alloc
)
138 std::set
<std::string
> r
;
139 for(auto i
: settings
)
144 void setting_group::set_storage_mode(bool enable
) throw()
146 storage_mode
= enable
;
149 std::map
<std::string
, std::string
> setting_group::get_invalid_values() throw(std::bad_alloc
)
152 return invalid_values
;
155 void setting_group::add_listener(struct setting_listener
& listener
) throw(std::bad_alloc
)
158 listeners
.insert(&listener
);
161 void setting_group::remove_listener(struct setting_listener
& listener
) throw(std::bad_alloc
)
164 listeners
.erase(&listener
);
167 void setting_group::do_register(const std::string
& name
, setting
& _setting
) throw(std::bad_alloc
)
170 settings
[name
] = &_setting
;
173 void setting_group::do_unregister(const std::string
& name
) throw(std::bad_alloc
)
176 settings
.erase(name
);
179 setting::setting(setting_group
& group
, const std::string
& name
) throw(std::bad_alloc
)
182 regqueue_t::do_register(group
, settingname
= name
, *this);
185 setting::~setting() throw()
187 regqueue_t::do_unregister(in_group
, settingname
);
190 bool setting::blank(bool really
) throw(std::bad_alloc
, std::runtime_error
)
195 numeric_setting::numeric_setting(setting_group
& group
, const std::string
& sname
, int32_t minv
, int32_t maxv
,
196 int32_t dflt
) throw(std::bad_alloc
)
197 : setting(group
, sname
)
204 bool numeric_setting::is_set() throw()
209 void numeric_setting::set(const std::string
& _value
) throw(std::bad_alloc
, std::runtime_error
)
211 int32_t v
= parse_value
<int32_t>(_value
);
212 if(v
< minimum
|| v
> maximum
) {
213 std::ostringstream x
;
214 x
<< "Value out of range (" << minimum
<< " - " << maximum
<< ")";
215 throw std::runtime_error(x
.str());
220 std::string
numeric_setting::get() throw(std::bad_alloc
)
222 std::ostringstream x
;
227 numeric_setting::operator int32_t() throw()
229 lock_holder
lck(this);
233 boolean_setting::boolean_setting(setting_group
& group
, const std::string
& sname
, bool dflt
) throw(std::bad_alloc
)
234 : setting(group
, sname
)
239 bool boolean_setting::is_set() throw()
244 void boolean_setting::set(const std::string
& v
) throw(std::bad_alloc
, std::runtime_error
)
246 switch(string_to_bool(v
)) {
254 throw std::runtime_error("Invalid value for boolean setting");
258 std::string
boolean_setting::get() throw(std::bad_alloc
)
266 boolean_setting::operator bool() throw()
268 lock_holder
lck(this);
272 path_setting::path_setting(setting_group
& group
, const std::string
& sname
) throw(std::bad_alloc
)
273 : setting(group
, sname
)
279 bool path_setting::blank(bool really
) throw(std::bad_alloc
, std::runtime_error
)
288 bool path_setting::is_set() throw()
293 void path_setting::set(const std::string
& value
) throw(std::bad_alloc
, std::runtime_error
)
304 std::string
path_setting::get() throw(std::bad_alloc
)
309 path_setting::operator std::string()
311 lock_holder
lck(this);