Game Lua Kernel: simplify a horrendous loop
This can't be done in a simple loop over all_children_range since splice_children modifies the source config. This adds a new getter method for a view over all tag names.
This commit is contained in:
parent
39729290df
commit
a52c5e133a
3 changed files with 30 additions and 13 deletions
|
@ -583,7 +583,7 @@ void config::clear_children_impl(config_key_type key)
|
|||
children_.erase(i);
|
||||
}
|
||||
|
||||
void config::splice_children(config& src, const std::string& key)
|
||||
void config::splice_children(config& src, config_key_type key)
|
||||
{
|
||||
child_map::iterator i_src = src.children_.find(key);
|
||||
if(i_src == src.children_.end()) {
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
#include "utils/const_clone.hpp"
|
||||
#include "utils/optional_reference.hpp"
|
||||
|
||||
#ifdef __cpp_lib_ranges
|
||||
#include <ranges>
|
||||
#else
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
|
@ -609,7 +615,7 @@ public:
|
|||
/**
|
||||
* Moves all the children with tag @a key from @a src to this.
|
||||
*/
|
||||
void splice_children(config &src, const std::string &key);
|
||||
void splice_children(config& src, config_key_type key);
|
||||
|
||||
void remove_child(config_key_type key, std::size_t index);
|
||||
/**
|
||||
|
@ -875,6 +881,16 @@ public:
|
|||
*/
|
||||
bool validate_wml() const;
|
||||
|
||||
/** A non-owning view over all child tag names. */
|
||||
auto child_name_view() const
|
||||
{
|
||||
#ifdef __cpp_lib_ranges
|
||||
return children_ | std::views::keys;
|
||||
#else
|
||||
return children_ | boost::adaptors::map_keys;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Removes the child at position @a pos of @a l.
|
||||
|
|
|
@ -5708,11 +5708,11 @@ void game_lua_kernel::set_game_display(game_display * gd) {
|
|||
* elsewhere (in the C++ code).
|
||||
* Any child tags not in this list will be passed to Lua's on_load event.
|
||||
*/
|
||||
static bool is_handled_file_tag(const std::string& s)
|
||||
static bool is_handled_file_tag(std::string_view s)
|
||||
{
|
||||
// Make sure this is sorted, since we binary_search!
|
||||
using namespace std::literals::string_view_literals;
|
||||
static const std::array handled_file_tags {
|
||||
static constexpr std::array handled_file_tags {
|
||||
"color_palette"sv,
|
||||
"color_range"sv,
|
||||
"display"sv,
|
||||
|
@ -5787,23 +5787,24 @@ void game_lua_kernel::save_game(config &cfg)
|
|||
luaW_toconfig(L, -1, v);
|
||||
lua_pop(L, 1);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
config::all_children_iterator i = v.ordered_begin();
|
||||
if (i == v.ordered_end()) break;
|
||||
if (is_handled_file_tag(i->key))
|
||||
{
|
||||
// Make a copy of the source tag names. Since splice is a destructive operation,
|
||||
// we can't guarantee that the view will remain valid during iteration.
|
||||
const auto temp = v.child_name_view();
|
||||
const std::vector<std::string> src_tags(temp.begin(), temp.end());
|
||||
|
||||
for(const auto& key : src_tags) {
|
||||
if(is_handled_file_tag(key)) {
|
||||
/*
|
||||
* It seems the only tags appearing in the config v variable here
|
||||
* are the core-lua-handled (currently [item] and [objectives])
|
||||
* and the extra UMC ones.
|
||||
*/
|
||||
const std::string m = "Tag is already used: [" + i->key + "]";
|
||||
const std::string m = "Tag is already used: [" + key + "]";
|
||||
log_error(m.c_str());
|
||||
v.erase(i);
|
||||
continue;
|
||||
} else {
|
||||
cfg.splice_children(v, key);
|
||||
}
|
||||
cfg.splice_children(v, i->key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue