1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-11-16 01:57:09 +00:00

range_checking_accessors class. makes sure setting's value belongs to a specified range

This commit is contained in:
Pavel Labath 2010-02-27 15:15:25 +01:00
parent 4a5304b395
commit f6aa8a558f
3 changed files with 51 additions and 11 deletions

View File

@ -4159,7 +4159,7 @@ int main(int argc, char **argv)
std::cout << "config.alignment = " << text_alignment.get(l) << std::endl; std::cout << "config.alignment = " << text_alignment.get(l) << std::endl;
l.loadstring( l.loadstring(
"print('config.asdf = ', conky.config.asdf);\n" "print('config.asdf = ', conky.config.asdf);\n"
"conky.config.asdf = 42;\n" "conky.config.asdf = -42;\n"
"print('config.asdf = ', conky.config.asdf);\n" "print('config.asdf = ', conky.config.asdf);\n"
"conky.config.alignment='asdf';\n" "conky.config.alignment='asdf';\n"
"print('config.alignment = ', conky.config.alignment);\n" "print('config.alignment = ', conky.config.alignment);\n"

View File

@ -162,5 +162,5 @@ namespace conky {
} }
/////////// example settings, remove after real settings are available /////// /////////// example settings, remove after real settings are available ///////
config_setting<std::string> asdf("asdf"); config_setting<int, range_checking_accessors<int>> asdf("asdf", range_checking_accessors<int>(42, 47, 45, true));
} }

View File

@ -24,6 +24,7 @@
#ifndef SETTING_HH #ifndef SETTING_HH
#define SETTING_HH #define SETTING_HH
#include <limits>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <unordered_map> #include <unordered_map>
@ -123,6 +124,7 @@ namespace conky {
const T default_value; const T default_value;
bool modifiable; bool modifiable;
protected:
std::pair<T, bool> do_convert(lua::state *l, int index, const std::string &name) std::pair<T, bool> do_convert(lua::state *l, int index, const std::string &name)
{ {
if(l->isnil(index)) if(l->isnil(index))
@ -138,6 +140,15 @@ namespace conky {
return Traits::convert(l, index, name); return Traits::convert(l, index, name);
} }
std::pair<T, bool> setter_check(lua::state *l, bool init, const std::string &name)
{
if(!init && !modifiable) {
NORM_ERR("Setting '%s' is not modifiable", name.c_str());
return {default_value, false};
} else
return do_convert(l, -2, name);
}
public: public:
simple_accessors(T default_value_ = T(), bool modifiable_ = false) simple_accessors(T default_value_ = T(), bool modifiable_ = false)
: default_value(default_value_), modifiable(modifiable_) : default_value(default_value_), modifiable(modifiable_)
@ -159,16 +170,45 @@ namespace conky {
{ {
lua::stack_sentry s(*l, -2); lua::stack_sentry s(*l, -2);
if(!init && !modifiable) { auto ret = setter_check(l, init, name);
NORM_ERR("Setting '%s' is not modifiable", name.c_str()); if(ret.second)
l->pop();
else
l->replace(-2); l->replace(-2);
} else { ++s;
auto ret = do_convert(l, -2, name); }
if(ret.second) };
l->pop();
else template<typename T, typename Traits = lua_traits<T>>
class range_checking_accessors: private simple_accessors<T, Traits> {
typedef simple_accessors<T, Traits> Base;
T min;
T max;
public:
range_checking_accessors(T min_ = -std::numeric_limits<T>::infinity(),
T max_ = std::numeric_limits<T>::infinity(),
T default_value_ = T(), bool modifiable_ = false)
: Base(default_value_, modifiable_), min(min_), max(max_)
{ assert(min_ <= default_value_ && default_value_ <= max_); }
using Base::getter;
void lua_setter(lua::state *l, bool init, const std::string &name)
{
lua::stack_sentry s(*l, -2);
auto ret = Base::setter_check(l, init, name);
if(ret.second) {
if(ret.first < min || ret.first > max) {
NORM_ERR("Value is out of range for setting '%s'", name.c_str());
// we ignore out-of-range values. an alternative would be to clamp them. do
// we want to do that?
l->replace(-2); l->replace(-2);
} } else
l->pop();
} else
l->replace(-2);
++s; ++s;
} }
}; };
@ -250,7 +290,7 @@ namespace conky {
} }
/////////// example settings, remove after real settings are available /////// /////////// example settings, remove after real settings are available ///////
extern config_setting<std::string> asdf; extern config_setting<int, range_checking_accessors<int>> asdf;
} }
#endif /* SETTING_HH */ #endif /* SETTING_HH */