Refactor ui::tagged_text to use allocated strings instead of string_views
This commit is contained in:
parent
b0fd3562cf
commit
2a2a97f0f8
5 changed files with 39 additions and 44 deletions
|
|
@ -102,17 +102,17 @@ namespace psemek::ui
|
||||||
|
|
||||||
struct text_chunk
|
struct text_chunk
|
||||||
{
|
{
|
||||||
std::string_view text;
|
std::string text;
|
||||||
text_style style; // to be OR'd with base style
|
text_style style; // to be OR'd with base style
|
||||||
std::optional<gfx::color_rgba> color;
|
std::optional<gfx::color_rgba> color;
|
||||||
std::optional<std::string_view> link;
|
std::optional<std::string> link;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct image_chunk
|
struct image_chunk
|
||||||
{
|
{
|
||||||
std::string_view id;
|
std::string id;
|
||||||
std::optional<gfx::color_rgba> color;
|
std::optional<gfx::color_rgba> color;
|
||||||
std::optional<std::string_view> link;
|
std::optional<std::string> link;
|
||||||
};
|
};
|
||||||
|
|
||||||
using chunk = std::variant<text_chunk, image_chunk>;
|
using chunk = std::variant<text_chunk, image_chunk>;
|
||||||
|
|
@ -139,12 +139,12 @@ namespace psemek::ui
|
||||||
std::vector<batch> batches;
|
std::vector<batch> batches;
|
||||||
geom::vector<float, 2> size{0.f, 0.f};
|
geom::vector<float, 2> size{0.f, 0.f};
|
||||||
|
|
||||||
std::vector<std::pair<geom::box<float, 2>, std::string_view>> link_bboxes;
|
std::vector<std::pair<geom::box<float, 2>, std::string>> link_bboxes;
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable std::optional<cached_state> cached_state_;
|
mutable std::optional<cached_state> cached_state_;
|
||||||
mutable std::optional<cached_state> cached_state_inf_;
|
mutable std::optional<cached_state> cached_state_inf_;
|
||||||
std::optional<std::string_view> selected_link_;
|
std::optional<std::string> selected_link_;
|
||||||
bool mouse_down_ = false;
|
bool mouse_down_ = false;
|
||||||
|
|
||||||
void update_cached_state() const;
|
void update_cached_state() const;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string_view>
|
#include <string>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
@ -16,16 +16,16 @@ namespace psemek::ui
|
||||||
{
|
{
|
||||||
struct opening_tag
|
struct opening_tag
|
||||||
{
|
{
|
||||||
std::string_view type;
|
std::string type;
|
||||||
std::optional<std::string_view> attribute;
|
std::optional<std::string> attribute;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct closing_tag
|
struct closing_tag
|
||||||
{
|
{
|
||||||
std::string_view type;
|
std::string type;
|
||||||
};
|
};
|
||||||
|
|
||||||
using token = std::variant<std::string_view, opening_tag, closing_tag>;
|
using token = std::variant<std::string, opening_tag, closing_tag>;
|
||||||
|
|
||||||
std::vector<token> tokens;
|
std::vector<token> tokens;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace psemek::ui
|
||||||
"link",
|
"link",
|
||||||
};
|
};
|
||||||
|
|
||||||
void check_attribute(std::string_view tag, std::optional<std::string_view> const & attribute)
|
void check_attribute(std::string const & tag, std::optional<std::string> const & attribute)
|
||||||
{
|
{
|
||||||
if (tag == "bold" || tag == "uline" || tag == "strike")
|
if (tag == "bold" || tag == "uline" || tag == "strike")
|
||||||
{
|
{
|
||||||
|
|
@ -65,11 +65,11 @@ namespace psemek::ui
|
||||||
|
|
||||||
auto parse_result = tagged_text::parse(text_);
|
auto parse_result = tagged_text::parse(text_);
|
||||||
|
|
||||||
std::unordered_map<std::string_view, std::vector<std::optional<std::string_view>>> tags_stack;
|
std::unordered_map<std::string, std::vector<std::optional<std::string>>> tags_stack;
|
||||||
|
|
||||||
for (auto const & token : parse_result.tokens)
|
for (auto const & token : parse_result.tokens)
|
||||||
{
|
{
|
||||||
if (auto text = std::get_if<std::string_view>(&token))
|
if (auto text = std::get_if<std::string>(&token))
|
||||||
{
|
{
|
||||||
text_chunk chunk;
|
text_chunk chunk;
|
||||||
if (!tags_stack["bold"].empty())
|
if (!tags_stack["bold"].empty())
|
||||||
|
|
@ -174,7 +174,7 @@ namespace psemek::ui
|
||||||
{
|
{
|
||||||
if (cached_state_)
|
if (cached_state_)
|
||||||
{
|
{
|
||||||
std::optional<std::string_view> new_selected_link;
|
std::optional<std::string> new_selected_link;
|
||||||
auto const p = geom::cast<float>(e.position);
|
auto const p = geom::cast<float>(e.position);
|
||||||
for (auto const & b : cached_state_->link_bboxes)
|
for (auto const & b : cached_state_->link_bboxes)
|
||||||
{
|
{
|
||||||
|
|
@ -341,7 +341,7 @@ namespace psemek::ui
|
||||||
text_style style;
|
text_style style;
|
||||||
gfx::color_rgba color;
|
gfx::color_rgba color;
|
||||||
gfx::texture_view_2d image;
|
gfx::texture_view_2d image;
|
||||||
std::optional<std::string_view> link;
|
std::optional<std::string> link;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<item> items;
|
std::vector<item> items;
|
||||||
|
|
|
||||||
|
|
@ -56,12 +56,9 @@ namespace psemek::ui
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto append = [&](std::string_view & target)
|
auto append = [&](std::string & target)
|
||||||
{
|
{
|
||||||
if (target.empty())
|
target.push_back(*current);
|
||||||
target = {current, current + 1};
|
|
||||||
else
|
|
||||||
target = {target.data(), current + 1};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (in_tag)
|
if (in_tag)
|
||||||
|
|
@ -83,17 +80,17 @@ namespace psemek::ui
|
||||||
++current;
|
++current;
|
||||||
if (current < text.end())
|
if (current < text.end())
|
||||||
{
|
{
|
||||||
result.tokens.push_back(std::string_view{});
|
result.tokens.push_back(std::string{});
|
||||||
append(std::get<std::string_view>(result.tokens.back()));
|
append(std::get<std::string>(result.tokens.back()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
--current;
|
--current;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (result.tokens.empty() || !std::get_if<std::string_view>(&result.tokens.back()))
|
if (result.tokens.empty() || !std::get_if<std::string>(&result.tokens.back()))
|
||||||
result.tokens.push_back(std::string_view{});
|
result.tokens.push_back(std::string{});
|
||||||
append(std::get<std::string_view>(result.tokens.back()));
|
append(std::get<std::string>(result.tokens.back()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ static void compare(tagged_text const & result, tagged_text const & expected)
|
||||||
for (std::size_t i = 0; i < result.tokens.size(); ++i)
|
for (std::size_t i = 0; i < result.tokens.size(); ++i)
|
||||||
{
|
{
|
||||||
expect_equal(result.tokens[i].index(), expected.tokens[i].index());
|
expect_equal(result.tokens[i].index(), expected.tokens[i].index());
|
||||||
if (auto token = std::get_if<std::string_view>(&result.tokens[i]))
|
if (auto token = std::get_if<std::string>(&result.tokens[i]))
|
||||||
{
|
{
|
||||||
expect_equal(*token, std::get<std::string_view>(expected.tokens[i]));
|
expect_equal(*token, std::get<std::string>(expected.tokens[i]));
|
||||||
}
|
}
|
||||||
else if (auto token = std::get_if<tagged_text::opening_tag>(&result.tokens[i]))
|
else if (auto token = std::get_if<tagged_text::opening_tag>(&result.tokens[i]))
|
||||||
{
|
{
|
||||||
|
|
@ -116,14 +116,12 @@ test_case(ui_tagged__text_random)
|
||||||
|
|
||||||
generator rng;
|
generator rng;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<std::string>> string_pool;
|
auto random_string = [&rng]() -> std::string {
|
||||||
|
std::string result;
|
||||||
auto random_string = [&rng, &string_pool]() -> std::string const & {
|
result.resize(uniform<int>(rng, 1, 10));
|
||||||
auto & result = string_pool.emplace_back(std::make_unique<std::string>());
|
for (char & c : result)
|
||||||
result->resize(uniform<int>(rng, 1, 10));
|
|
||||||
for (char & c : *result)
|
|
||||||
c = uniform<char>(rng, 'a', 'z');
|
c = uniform<char>(rng, 'a', 'z');
|
||||||
return *result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string text;
|
std::string text;
|
||||||
|
|
@ -133,14 +131,14 @@ test_case(ui_tagged__text_random)
|
||||||
{
|
{
|
||||||
auto roll = uniform<int>(rng, 0, 2);
|
auto roll = uniform<int>(rng, 0, 2);
|
||||||
|
|
||||||
if (!expected.tokens.empty() && std::get_if<std::string_view>(&expected.tokens.back()) && roll == 0)
|
if (!expected.tokens.empty() && std::get_if<std::string>(&expected.tokens.back()) && roll == 0)
|
||||||
roll = uniform<int>(rng, 1, 2);
|
roll = uniform<int>(rng, 1, 2);
|
||||||
|
|
||||||
if (roll == 0)
|
if (roll == 0)
|
||||||
{
|
{
|
||||||
auto const & str = random_string();
|
auto str = random_string();
|
||||||
text += str;
|
text += str;
|
||||||
expected.tokens.push_back(std::string_view{str});
|
expected.tokens.push_back(std::move(str));
|
||||||
}
|
}
|
||||||
else if (roll == 1)
|
else if (roll == 1)
|
||||||
{
|
{
|
||||||
|
|
@ -148,16 +146,16 @@ test_case(ui_tagged__text_random)
|
||||||
|
|
||||||
tagged_text::opening_tag token;
|
tagged_text::opening_tag token;
|
||||||
|
|
||||||
auto const & tag_str = random_string();
|
auto tag_str = random_string();
|
||||||
|
|
||||||
text += "[" + tag_str;
|
text += "[" + tag_str;
|
||||||
token.type = tag_str;
|
token.type = std::move(tag_str);
|
||||||
|
|
||||||
if (has_attr)
|
if (has_attr)
|
||||||
{
|
{
|
||||||
auto const & attr_str = random_string();
|
auto attr_str = random_string();
|
||||||
text += ":" + attr_str;
|
text += ":" + attr_str;
|
||||||
token.attribute = std::string_view{attr_str};
|
token.attribute = std::move(attr_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
text += "]";
|
text += "]";
|
||||||
|
|
@ -168,10 +166,10 @@ test_case(ui_tagged__text_random)
|
||||||
{
|
{
|
||||||
tagged_text::closing_tag token;
|
tagged_text::closing_tag token;
|
||||||
|
|
||||||
auto const & tag_str = random_string();
|
auto tag_str = random_string();
|
||||||
|
|
||||||
text += "[/" + tag_str + "]";
|
text += "[/" + tag_str + "]";
|
||||||
token.type = tag_str;
|
token.type = std::move(tag_str);
|
||||||
|
|
||||||
expected.tokens.push_back(token);
|
expected.tokens.push_back(token);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue