Added bool type to ObjectConverter, Serializer and Deserializer

0.8
Bruno Van de Velde 2017-09-05 20:25:21 +02:00
parent f2ea459b27
commit 6926f29dea
9 changed files with 133 additions and 58 deletions

View File

@ -55,6 +55,7 @@ namespace tgui
enum class Type
{
None,
Bool,
Font,
Color,
String,
@ -80,9 +81,30 @@ namespace tgui
/// @brief Stores a string for later retrieval
///
/// @param string String to store
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectConverter(const sf::String& string) :
ObjectConverter(const char* string) :
ObjectConverter{sf::String{string}}
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Stores a string for later retrieval
///
/// @param string String to store
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectConverter(const std::string& string) :
ObjectConverter{sf::String{string}}
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Stores a string for later retrieval
///
/// @param string String to store
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectConverter(const sf::String& string) :
m_type {Type::String},
m_value {string},
m_serialized{true},
@ -111,7 +133,7 @@ namespace tgui
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectConverter(sf::Color color) :
ObjectConverter(Color(color))
ObjectConverter(Color{color})
{
}
@ -129,15 +151,28 @@ namespace tgui
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Stores a boolean for later retrieval
///
/// @param value Boolean to store
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectConverter(bool value) :
m_type {Type::Bool},
m_value{value}
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Stores a number for later retrieval
///
/// @param number Number to store
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectConverter(float number) :
template <typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
ObjectConverter(T number) :
m_type {Type::Number},
m_value{number}
m_value{static_cast<float>(number)}
{
}
@ -250,6 +285,16 @@ namespace tgui
const Outline& getOutline();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Retrieves the saved boolean
///
/// @return The saved boolean
///
/// This function will assert when something other than a boolean was saved
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool getBool();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Retrieves the saved number
///
@ -308,7 +353,7 @@ namespace tgui
Type m_type = Type::None;
#ifdef TGUI_USE_VARIANT
std::variant<sf::String, Font, Color, Outline, float, Texture, TextStyle, std::shared_ptr<RendererData>> m_value;
std::variant<sf::String, Font, Color, Outline, bool, float, Texture, TextStyle, std::shared_ptr<RendererData>> m_value;
#else
Any m_value;
#endif

View File

@ -123,19 +123,6 @@ namespace tgui
Font getFont() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes a property of the renderer
///
/// @param property The property that you would like to change
/// @param value The new value that you like to assign to the property.
/// The value can either be a string value or a serialized string
///
/// @throw Exception for unknown properties or when value was of a wrong type
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setProperty(const std::string& property, const std::string& value);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes a property of the renderer
///

View File

@ -72,6 +72,19 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectConverter deserializeBool(const std::string& value)
{
const std::string str = toLower(value);
if (str == "true" || str == "yes" || str == "on" || str == "1")
return {true};
else if (str == "false" || str == "no" || str == "off" || str == "0")
return {false};
else
throw Exception{"Failed to deserialize boolean from '" + str + "'"};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectConverter deserializeFont(const std::string& value)
{
if (value == "null" || value == "nullptr")
@ -420,6 +433,7 @@ namespace tgui
std::map<ObjectConverter::Type, Deserializer::DeserializeFunc> Deserializer::m_deserializers =
{
{ObjectConverter::Type::Bool, deserializeBool},
{ObjectConverter::Type::Font, deserializeFont},
{ObjectConverter::Type::Color, deserializeColor},
{ObjectConverter::Type::String, deserializeString},

View File

@ -74,6 +74,16 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::string serializeBool(ObjectConverter&& value)
{
if (value.getBool())
return "true";
else
return "false";
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::string serializeFont(ObjectConverter&& value)
{
if (value.getFont() && !value.getFont().getId().empty())
@ -240,6 +250,7 @@ namespace tgui
std::map<ObjectConverter::Type, Serializer::SerializeFunc> Serializer::m_serializers =
{
{ObjectConverter::Type::None, serializeEmptyObject},
{ObjectConverter::Type::Bool, serializeBool},
{ObjectConverter::Type::Font, serializeFont},
{ObjectConverter::Type::Color, serializeColor},
{ObjectConverter::Type::String, serializeString},

View File

@ -71,19 +71,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool parseBoolean(std::string str)
{
str = toLower(str);
if (str == "true" || str == "yes" || str == "on" || str == "1")
return true;
else if (str == "false" || str == "no" || str == "off" || str == "0")
return false;
else
throw Exception{"Failed to parse boolean in '" + str + "'"};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sf::Vector2f parseVector2f(std::string str)
{
if (str.empty())
@ -133,7 +120,7 @@ namespace tgui
if (node->propertyValuePairs["visible"])
{
bool visible = parseBoolean(node->propertyValuePairs["visible"]->value);
bool visible = Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["visible"]->value).getBool();
if (visible)
widget->show();
else
@ -141,7 +128,7 @@ namespace tgui
}
if (node->propertyValuePairs["enabled"])
{
bool enabled = parseBoolean(node->propertyValuePairs["enabled"]->value);
bool enabled = Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["enabled"]->value).getBool();
if (enabled)
widget->enable();
else
@ -305,11 +292,11 @@ namespace tgui
REMOVE_CHILD("line");
if (node->propertyValuePairs["linesstartfromtop"])
chatBox->setLinesStartFromTop(parseBoolean(node->propertyValuePairs["linesstartfromtop"]->value));
chatBox->setLinesStartFromTop(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["linesstartfromtop"]->value).getBool());
// This has to be parsed after the lines have been added
if (node->propertyValuePairs["newlinesbelowothers"])
chatBox->setNewLinesBelowOthers(parseBoolean(node->propertyValuePairs["newlinesbelowothers"]->value));
chatBox->setNewLinesBelowOthers(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["newlinesbelowothers"]->value).getBool());
return chatBox;
}
@ -330,10 +317,10 @@ namespace tgui
if (node->propertyValuePairs["textsize"])
checkbox->setTextSize(tgui::stoi(node->propertyValuePairs["textsize"]->value));
if (node->propertyValuePairs["textclickable"])
checkbox->setTextClickable(parseBoolean(node->propertyValuePairs["textclickable"]->value));
checkbox->setTextClickable(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["textclickable"]->value).getBool());
if (node->propertyValuePairs["checked"])
{
if (parseBoolean(node->propertyValuePairs["checked"]->value))
if (Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["checked"]->value).getBool())
checkbox->check();
}
@ -384,10 +371,10 @@ namespace tgui
childWindow->setTitle(DESERIALIZE_STRING("title"));
if (node->propertyValuePairs["keepinparent"])
childWindow->keepInParent(parseBoolean(node->propertyValuePairs["keepinparent"]->value));
childWindow->keepInParent(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["keepinparent"]->value).getBool());
if (node->propertyValuePairs["resizable"])
childWindow->setResizable(parseBoolean(node->propertyValuePairs["resizable"]->value));
childWindow->setResizable(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["resizable"]->value).getBool());
if (node->propertyValuePairs["minimumsize"])
childWindow->setMinimumSize(parseVector2f(node->propertyValuePairs["minimumsize"]->value));
@ -490,7 +477,7 @@ namespace tgui
if (node->propertyValuePairs["maximumcharacters"])
editBox->setMaximumCharacters(tgui::stoi(node->propertyValuePairs["maximumcharacters"]->value));
if (node->propertyValuePairs["textwidthlimited"])
editBox->limitTextWidth(parseBoolean(node->propertyValuePairs["textwidthlimited"]->value));
editBox->limitTextWidth(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["textwidthlimited"]->value).getBool());
if (node->propertyValuePairs["passwordcharacter"])
{
std::string pass = DESERIALIZE_STRING("passwordcharacter");
@ -536,7 +523,7 @@ namespace tgui
loadContainer(node, grid);
if (node->propertyValuePairs["autosize"])
grid->setAutoSize(parseBoolean(node->propertyValuePairs["autosize"]->value));
grid->setAutoSize(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["autosize"]->value).getBool());
if (node->propertyValuePairs["gridwidgets"])
{
@ -683,7 +670,7 @@ namespace tgui
if (node->propertyValuePairs["value"])
knob->setValue(tgui::stoi(node->propertyValuePairs["value"]->value));
if (node->propertyValuePairs["clockwiseturning"])
knob->setClockwiseTurning(parseBoolean(node->propertyValuePairs["clockwiseturning"]->value));
knob->setClockwiseTurning(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["clockwiseturning"]->value).getBool());
return knob;
}
@ -729,7 +716,7 @@ namespace tgui
if (node->propertyValuePairs["maximumtextwidth"])
label->setMaximumTextWidth(tgui::stof(node->propertyValuePairs["maximumtextwidth"]->value));
if (node->propertyValuePairs["autosize"])
label->setAutoSize(parseBoolean(node->propertyValuePairs["autosize"]->value));
label->setAutoSize(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["autosize"]->value).getBool());
return label;
}
@ -784,7 +771,7 @@ namespace tgui
}
if (node->propertyValuePairs["autoscroll"])
listBox->setAutoScroll(parseBoolean(node->propertyValuePairs["autoscroll"]->value));
listBox->setAutoScroll(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["autoscroll"]->value).getBool());
if (node->propertyValuePairs["textsize"])
listBox->setTextSize(tgui::stoi(node->propertyValuePairs["textsize"]->value));
if (node->propertyValuePairs["itemheight"])
@ -942,10 +929,10 @@ namespace tgui
if (node->propertyValuePairs["textsize"])
radioButton->setTextSize(tgui::stoi(node->propertyValuePairs["textsize"]->value));
if (node->propertyValuePairs["textclickable"])
radioButton->setTextClickable(parseBoolean(node->propertyValuePairs["textclickable"]->value));
radioButton->setTextClickable(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["textclickable"]->value).getBool());
if (node->propertyValuePairs["checked"])
{
if (parseBoolean(node->propertyValuePairs["checked"]->value))
if (Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["checked"]->value).getBool())
radioButton->check();
}
@ -1023,7 +1010,7 @@ namespace tgui
if (node->propertyValuePairs["scrollamount"])
scrollbar->setScrollAmount(tgui::stoi(node->propertyValuePairs["scrollamount"]->value));
if (node->propertyValuePairs["autohide"])
scrollbar->setAutoHide(parseBoolean(node->propertyValuePairs["autohide"]->value));
scrollbar->setAutoHide(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["autohide"]->value).getBool());
return scrollbar;
}
@ -1067,7 +1054,7 @@ namespace tgui
if (node->propertyValuePairs["value"])
spinButton->setValue(tgui::stoi(node->propertyValuePairs["value"]->value));
if (node->propertyValuePairs["verticalscroll"])
spinButton->setVerticalScroll(parseBoolean(node->propertyValuePairs["verticalscroll"]->value));
spinButton->setVerticalScroll(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["verticalscroll"]->value).getBool());
return spinButton;
}
@ -1124,9 +1111,9 @@ namespace tgui
if (node->propertyValuePairs["maximumcharacters"])
textBox->setMaximumCharacters(tgui::stoi(node->propertyValuePairs["maximumcharacters"]->value));
if (node->propertyValuePairs["readonly"])
textBox->setReadOnly(parseBoolean(node->propertyValuePairs["readonly"]->value));
textBox->setReadOnly(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["readonly"]->value).getBool());
if (node->propertyValuePairs["verticalscrollbarpresent"])
textBox->setVerticalScrollbarPresent(parseBoolean(node->propertyValuePairs["verticalscrollbarpresent"]->value));
textBox->setVerticalScrollbarPresent(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["verticalscrollbarpresent"]->value).getBool());
return textBox;
}

View File

@ -88,6 +88,26 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ObjectConverter::getBool()
{
assert(m_type != Type::None);
assert(m_type == Type::Bool || m_type == Type::String);
if (m_type == Type::String)
{
m_value = Deserializer::deserialize(ObjectConverter::Type::Bool, m_string).getBool();
m_type = Type::Bool;
}
#ifdef TGUI_USE_VARIANT
return std::get<bool>(m_value);
#else
return m_value.as<bool>();
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float ObjectConverter::getNumber()
{
assert(m_type != Type::None);

View File

@ -64,13 +64,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void WidgetRenderer::setProperty(const std::string& property, const std::string& value)
{
setProperty(property, ObjectConverter{sf::String{value}});
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void WidgetRenderer::setProperty(const std::string& property, ObjectConverter&& value)
{
std::string lowercaseProperty = toLower(property);

View File

@ -29,6 +29,18 @@ using Type = tgui::ObjectConverter::Type;
TEST_CASE("[Deserializer]")
{
SECTION("deserialize bool")
{
REQUIRE(tgui::Deserializer::deserialize(tgui::ObjectConverter::Type::Bool, "True").getBool());
REQUIRE(!tgui::Deserializer::deserialize(tgui::ObjectConverter::Type::Bool, "FALSE").getBool());
REQUIRE(tgui::Deserializer::deserialize(tgui::ObjectConverter::Type::Bool, "YeS").getBool());
REQUIRE(!tgui::Deserializer::deserialize(tgui::ObjectConverter::Type::Bool, "nO").getBool());
REQUIRE(tgui::Deserializer::deserialize(tgui::ObjectConverter::Type::Bool, "1").getBool());
REQUIRE(!tgui::Deserializer::deserialize(tgui::ObjectConverter::Type::Bool, "0").getBool());
REQUIRE_THROWS_AS(tgui::Deserializer::deserialize(Type::Bool, "InvalidString"), tgui::Exception);
}
SECTION("deserialize font")
{
REQUIRE(tgui::Deserializer::deserialize(tgui::ObjectConverter::Type::Font, "resources/DejaVuSans.ttf").getFont() != nullptr);

View File

@ -32,6 +32,12 @@ TEST_CASE("[Serializer]")
REQUIRE_THROWS_AS(tgui::Serializer::serialize({}), tgui::Exception);
}
SECTION("serialize bool")
{
REQUIRE(tgui::Serializer::serialize({false}) == "false");
REQUIRE(tgui::Serializer::serialize({true}) == "true");
}
SECTION("serialize font")
{
tgui::Font font{"resources/DejaVuSans.ttf"};