mirror of
https://github.com/OpenMW/openmw.git
synced 2025-10-16 14:16:33 +00:00
Use a custom formatter to limit float precision
This commit is contained in:
parent
d4a1061354
commit
eb01a302f1
3 changed files with 73 additions and 9 deletions
|
@ -30,6 +30,50 @@
|
||||||
|
|
||||||
#include "itemmodel.hpp"
|
#include "itemmodel.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template <unsigned short Precision = 2>
|
||||||
|
struct LimitedFloat
|
||||||
|
{
|
||||||
|
float mValue;
|
||||||
|
|
||||||
|
constexpr unsigned short getPrecision() { return Precision; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct std::formatter<LimitedFloat<>, char>
|
||||||
|
{
|
||||||
|
template <class ParseContext>
|
||||||
|
constexpr ParseContext::iterator parse(ParseContext& ctx)
|
||||||
|
{
|
||||||
|
return ctx.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class FmtContext>
|
||||||
|
FmtContext::iterator format(LimitedFloat<> v, FmtContext& ctx) const
|
||||||
|
{
|
||||||
|
constexpr unsigned short precision = v.getPrecision();
|
||||||
|
// FLOAT_MAX needs 39 digits + 1 for the sign + 1 for the decimal separator
|
||||||
|
constexpr std::size_t bufferSize = 41 + precision;
|
||||||
|
char buffer[bufferSize];
|
||||||
|
std::to_chars_result result
|
||||||
|
= std::to_chars(buffer, buffer + bufferSize, v.mValue, std::chars_format::fixed, precision);
|
||||||
|
if (result.ec != std::errc())
|
||||||
|
{
|
||||||
|
// Should never happen, but just default to regular float formatting
|
||||||
|
return std::format_to(ctx.out(), "{}", v.mValue);
|
||||||
|
}
|
||||||
|
// Trim result so 1.00 turns into 1
|
||||||
|
char* end = result.ptr;
|
||||||
|
while (end > buffer && *(end - 1) == '0')
|
||||||
|
--end;
|
||||||
|
if (end > buffer && *(end - 1) == '.')
|
||||||
|
--end;
|
||||||
|
return std::ranges::copy(buffer, end, ctx.out()).out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
ToolTips::ToolTips()
|
ToolTips::ToolTips()
|
||||||
|
@ -643,13 +687,7 @@ namespace MWGui
|
||||||
|
|
||||||
std::string ToolTips::toString(const float value)
|
std::string ToolTips::toString(const float value)
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
return std::format("{}", LimitedFloat(value));
|
||||||
|
|
||||||
if (value != int(value))
|
|
||||||
stream << std::setprecision(3);
|
|
||||||
|
|
||||||
stream << value;
|
|
||||||
return stream.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToolTips::toString(const int value)
|
std::string ToolTips::toString(const int value)
|
||||||
|
@ -661,14 +699,14 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
if (weight == 0)
|
if (weight == 0)
|
||||||
return {};
|
return {};
|
||||||
return std::format("\n{}: {}", prefix, toString(weight));
|
return std::format("\n{}: {}", prefix, LimitedFloat(weight));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToolTips::getPercentString(const float value, std::string_view prefix)
|
std::string ToolTips::getPercentString(const float value, std::string_view prefix)
|
||||||
{
|
{
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
return {};
|
return {};
|
||||||
return std::format("\n{}: {}%", prefix, toString(value * 100));
|
return std::format("\n{}: {}%", prefix, LimitedFloat(value * 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToolTips::getValueString(const int value, std::string_view prefix)
|
std::string ToolTips::getValueString(const int value, std::string_view prefix)
|
||||||
|
|
|
@ -14,6 +14,8 @@ file(GLOB UNITTEST_SRC_FILES
|
||||||
|
|
||||||
mwdialogue/testkeywordsearch.cpp
|
mwdialogue/testkeywordsearch.cpp
|
||||||
|
|
||||||
|
mwgui/tooltips.cpp
|
||||||
|
|
||||||
mwscript/testscripts.cpp
|
mwscript/testscripts.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
24
apps/openmw_tests/mwgui/tooltips.cpp
Normal file
24
apps/openmw_tests/mwgui/tooltips.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "apps/openmw/mwgui/tooltips.hpp"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
TEST(MWGuiToolTipsTest, floatsShouldBeFormattedCorrectly)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(ToolTips::toString(1.f), "1");
|
||||||
|
EXPECT_EQ(ToolTips::toString(1.1f), "1.1");
|
||||||
|
EXPECT_EQ(ToolTips::toString(1.12f), "1.12");
|
||||||
|
EXPECT_EQ(ToolTips::toString(1234567.12f), "1234567.12");
|
||||||
|
EXPECT_EQ(ToolTips::toString(0.001f), "0");
|
||||||
|
EXPECT_EQ(ToolTips::toString(0.01f), "0.01");
|
||||||
|
EXPECT_EQ(ToolTips::toString(0.01f), "0.01");
|
||||||
|
EXPECT_EQ(ToolTips::toString(std::numeric_limits<float>::infinity()), "inf");
|
||||||
|
EXPECT_EQ(ToolTips::toString(std::numeric_limits<float>::quiet_NaN()), "nan");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue