From e9abb212bb930083b34d0cab3b165147242bcdce Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Tue, 10 May 2022 22:55:41 -0600 Subject: [PATCH] settings: allow setting_enum to parse numeric representation of enums use it for light forumla. disallow enums in setting_numeric. --- common/settings.cc | 6 ++++++ include/common/settings.hh | 17 +++++++++++++++-- include/light/entities.hh | 3 ++- light/test_light.cc | 38 +++++++++++++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/common/settings.cc b/common/settings.cc index aa111596..c08e8b5d 100644 --- a/common/settings.cc +++ b/common/settings.cc @@ -34,6 +34,12 @@ setting_base::setting_base( } } +bool setting_base::parseString(const std::string &string, bool locked) +{ + parser_t p{string}; + return parse("", p, locked); +} + setting_group performance_group{"Performance", 10}; setting_group logging_group{"Logging", 5}; setting_group game_group{"Game", 15}; diff --git a/include/common/settings.hh b/include/common/settings.hh index 7a9836b9..6dbb3b43 100644 --- a/include/common/settings.hh +++ b/include/common/settings.hh @@ -174,6 +174,9 @@ public: // copies value and source virtual bool copyFrom(const setting_base& other) = 0; + // convenience form of parse() that constructs a temporary parser_t + bool parseString(const std::string &string, bool locked = false); + // resets value to default, and source to source::DEFAULT virtual void reset() = 0; virtual bool parse(const std::string &settingName, parser_base_t &parser, bool locked = false) = 0; @@ -387,6 +390,7 @@ public: template class setting_numeric : public setting_value { + static_assert(!std::is_enum_v, "use setting_enum for enums"); protected: T _min, _max; @@ -415,7 +419,6 @@ public: Q_assert(this->_value <= _max); } - template>> inline setting_numeric(setting_container *dictionary, const nameset &names, T v, const setting_group *group = nullptr, const char *description = "") : setting_numeric( @@ -423,7 +426,6 @@ public: { } - template>> inline bool boolValue() const { return this->_value > 0; @@ -507,11 +509,22 @@ public: return false; } + // see if it's a string enum case label if (auto it = _values.find(parser.token); it != _values.end()) { this->setValueFromParse(it->second, locked); return true; } + // see if it's an integer + try { + const int i = std::stoi(parser.token); + + this->setValueFromParse(static_cast(i), locked); + return true; + } catch (std::invalid_argument &) { + } catch (std::out_of_range &) { + } + return false; } }; diff --git a/include/light/entities.hh b/include/light/entities.hh index 02d05541..b0055802 100644 --- a/include/light/entities.hh +++ b/include/light/entities.hh @@ -70,7 +70,8 @@ public: settings::setting_scalar light{this, "light", DEFAULTLIGHTLEVEL}; settings::setting_scalar atten{this, "wait", 1.0, 0.0, std::numeric_limits::max()}; - settings::setting_numeric formula{this, "delay", LF_LINEAR, LF_LINEAR, LF_INVERSE2A}; + settings::setting_enum formula{this, "delay", LF_LINEAR, + {{"linear", LF_LINEAR}, {"inverse", LF_INVERSE}, {"inverse2", LF_INVERSE2}, {"infinite", LF_INFINITE}, {"localmin", LF_LOCALMIN}, {"inverse2a", LF_INVERSE2A}}}; settings::setting_scalar spotangle{this, "angle", 40.0}; settings::setting_scalar spotangle2{this, "softangle", 0.0}; settings::setting_numeric style{this, "style", 0, 0, 254}; diff --git a/light/test_light.cc b/light/test_light.cc index 5aa4f30d..04ea4cf6 100644 --- a/light/test_light.cc +++ b/light/test_light.cc @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include +#include #include #include // for std::sort @@ -917,4 +918,39 @@ TEST(trace, clamp_texcoord) EXPECT_EQ(0, clamp_texcoord(-127.5f, 128)); EXPECT_EQ(0, clamp_texcoord(-128.0f, 128)); EXPECT_EQ(127, clamp_texcoord(-129.0f, 128)); -} \ No newline at end of file +} + +TEST(settings, delayDefault) +{ + light_t light; + EXPECT_EQ(LF_LINEAR, light.formula.value()); +} + +TEST(settings, delayParseInt) +{ + light_t light; + EXPECT_TRUE(light.formula.parseString("2")); + EXPECT_EQ(LF_INVERSE2, light.formula.value()); +} + +TEST(settings, delayParseIntUnknown) +{ + light_t light; + EXPECT_TRUE(light.formula.parseString("500")); + // not sure if we should be strict and reject parsing this? + EXPECT_EQ(500, light.formula.value()); +} + +TEST(settings, delayParseFloat) +{ + light_t light; + EXPECT_TRUE(light.formula.parseString("2.0")); + EXPECT_EQ(LF_INVERSE2, light.formula.value()); +} + +TEST(settings, delayParseString) +{ + light_t light; + EXPECT_TRUE(light.formula.parseString("inverse2")); + EXPECT_EQ(LF_INVERSE2, light.formula.value()); +}