From fa12518f86dfb5039d11542450eb8a3116de133c Mon Sep 17 00:00:00 2001 From: Jyrki Vesterinen Date: Tue, 23 Oct 2018 22:49:34 +0300 Subject: [PATCH] Changed data type of display::get_overlays() `std::multimap` is a poor fit after commit 082aa2afe24815c1c432341e9fa9dd0d84da04a8 because `std::multimap` doesn't allow reordering of elements assigned to the same key. --- src/display.cpp | 111 ++++++++++++--------------------- src/display.hpp | 3 +- src/editor/map/map_context.cpp | 28 ++++----- src/editor/map/map_context.hpp | 4 +- 4 files changed, 59 insertions(+), 87 deletions(-) diff --git a/src/display.cpp b/src/display.cpp index 9160b5ce8eee..23120c5af38b 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -53,6 +53,7 @@ #include +#include #include #include #include @@ -94,13 +95,14 @@ void display::parse_team_overlays() const team& prev_team = playing_team() == 0 ? dc_->teams().back() : dc_->get_team(playing_team()); - for (const game_display::overlay_map::value_type i : get_overlays()) { - const overlay& ov = i.second; - if (!ov.team_name.empty() && - ((ov.team_name.find(curr_team.team_name()) + 1) != 0) != - ((ov.team_name.find(prev_team.team_name()) + 1) != 0)) - { - invalidate(i.first); + for (const auto& i : get_overlays()) { + for(const overlay& ov : i.second) { + if(!ov.team_name.empty() && + ((ov.team_name.find(curr_team.team_name()) + 1) != 0) != + ((ov.team_name.find(prev_team.team_name()) + 1) != 0)) + { + invalidate(i.first); + } } } } @@ -115,58 +117,27 @@ void display::add_overlay(const map_location& loc, const std::string& img, const get_location_y(loc) + hex_size() / 2, halo, loc); } - auto it1 = get_overlays().emplace(loc, overlay(img, halo, halo_handle, team_name, item_id, visible_under_fog, z_order)); - auto itor_pair = get_overlays().equal_range(loc); - //get_overlays().emplace adds at the end. - assert(itor_pair.second != itor_pair.first && std::next(it1, 1) == itor_pair.second); - UNUSED(it1); //it is only used in the assert above. - if(std::next(itor_pair.first, 1) != itor_pair.second) { - //the range itor_pair is already sorted, except for the last element we just inserted, - for (auto it = itor_pair.second; it != std::next(itor_pair.first, 1);--it) { - overlay& one = std::next(it, - 1)->second; - overlay& two = (it)->second; - if(one.z_order > two.z_order) { - std::swap(one, two); - } - } - } + std::vector& overlays = get_overlays()[loc]; + auto it = std::find_if(overlays.begin(), overlays.end(), [z_order](const overlay& ov) { return ov.z_order > z_order; }); + overlays.emplace(it, img, halo, halo_handle, team_name, item_id, visible_under_fog, z_order); } } void display::remove_overlay(const map_location& loc) { - /* This code no longer needed because of RAII in halo::handles - if (halo_man_) { - typedef overlay_map::const_iterator Itor; - std::pair itors = get_overlays().equal_range(loc); - while(itors.first != itors.second) { - halo_man_->remove(itors.first->second.halo_handle); - ++itors.first; - } - } - */ - get_overlays().erase(loc); } void display::remove_single_overlay(const map_location& loc, const std::string& toDelete) { - //Iterate through the values with key of loc - typedef overlay_map::iterator Itor; - overlay_map::iterator iteratorCopy; - std::pair itors = get_overlays().equal_range(loc); - while(itors.first != itors.second) { - //If image or halo of overlay struct matches toDelete, remove the overlay - if(itors.first->second.image == toDelete || itors.first->second.halo == toDelete || itors.first->second.id == toDelete) { - iteratorCopy = itors.first; - ++itors.first; - //Not needed because of RAII --> halo_man_->remove(iteratorCopy->second.halo_handle); - get_overlays().erase(iteratorCopy); - } - else { - ++itors.first; - } - } + std::vector& overlays = get_overlays()[loc]; + overlays.erase( + std::remove_if( + overlays.begin(), overlays.end(), + [&toDelete](const overlay& ov) { return ov.image == toDelete || ov.halo == toDelete || ov.id == toDelete; } + ), + overlays.end() + ); } display::display(const display_context * dc, std::weak_ptr wb, reports & reports_object, const config& theme_cfg, const config& level, bool auto_join) : @@ -2603,28 +2574,26 @@ void display::draw_hex(const map_location& loc) { } if(!shrouded(loc)) { - typedef overlay_map::const_iterator Itor; - std::pair overlays = get_overlays().equal_range(loc); - const bool have_overlays = overlays.first != overlays.second; - - if(have_overlays) { - tod_color tod_col = tod.color + color_adjust_; - image::light_string lt = image::get_light_string(-1, tod_col.r, tod_col.g, tod_col.b); - - for( ; overlays.first != overlays.second; ++overlays.first) { - const std::string& current_team_name = get_teams()[viewing_team()].team_name(); - const std::vector& current_team_names = utils::split(current_team_name); - const std::vector& team_names = utils::split(overlays.first->second.team_name); - if ((overlays.first->second.team_name.empty() || - std::find_first_of(team_names.begin(), team_names.end(), - current_team_names.begin(), current_team_names.end()) != team_names.end()) - && !(fogged(loc) && !overlays.first->second.visible_in_fog)) - { - - const std::string image = overlays.first->second.image; - const surface surf = image.find("~NO_TOD_SHIFT()") == std::string::npos ? - image::get_lighted_image(image, lt, image::SCALED_TO_HEX) : image::get_image(image, image::SCALED_TO_HEX); - drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, surf); + auto it = get_overlays().find(loc); + if(it != get_overlays().end()) { + std::vector& overlays = it->second; + if(overlays.size() != 0) { + tod_color tod_col = tod.color + color_adjust_; + image::light_string lt = image::get_light_string(-1, tod_col.r, tod_col.g, tod_col.b); + + for(const overlay& ov : overlays) { + const std::string& current_team_name = get_teams()[viewing_team()].team_name(); + const std::vector& current_team_names = utils::split(current_team_name); + const std::vector& team_names = utils::split(ov.team_name); + if((ov.team_name.empty() || + std::find_first_of(team_names.begin(), team_names.end(), + current_team_names.begin(), current_team_names.end()) != team_names.end()) + && !(fogged(loc) && !ov.visible_in_fog)) + { + const surface surf = ov.image.find("~NO_TOD_SHIFT()") == std::string::npos ? + image::get_lighted_image(ov.image, lt, image::SCALED_TO_HEX) : image::get_image(ov.image, image::SCALED_TO_HEX); + drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, surf); + } } } } diff --git a/src/display.hpp b/src/display.hpp index 401e55b37368..545207e68a52 100644 --- a/src/display.hpp +++ b/src/display.hpp @@ -71,6 +71,7 @@ namespace wb { #include #include #include +#include class gamemap; @@ -1026,7 +1027,7 @@ class display : public video2::draw_layering bool reach_map_changed_; void process_reachmap_changes(); - typedef std::multimap overlay_map; + typedef std::map> overlay_map; virtual overlay_map& get_overlays() = 0; diff --git a/src/editor/map/map_context.cpp b/src/editor/map/map_context.cpp index 610655349994..9abeac9c341a 100644 --- a/src/editor/map/map_context.cpp +++ b/src/editor/map/map_context.cpp @@ -343,7 +343,7 @@ void map_context::load_scenario(const config& game_config) for(const config& item : scenario.child_range("item")) { const map_location loc(item); - overlays_.emplace(loc, overlay(item)); + overlays_[loc].push_back(overlay(item)); } for(const config& music : scenario.child_range("music")) { @@ -491,22 +491,22 @@ config map_context::to_config() labels_.write(scenario); for(const auto& overlay_pair : overlays_) { - config& item = scenario.add_child("item"); + for(const overlay& o : overlay_pair.second) { + config& item = scenario.add_child("item"); - // Write x,y location - overlay_pair.first.write(item); + // Write x,y location + overlay_pair.first.write(item); - const overlay& o = overlay_pair.second; + // These should always have a value + item["image"] = o.image; + item["visible_in_fog"] = o.visible_in_fog; - // These should always have a value - item["image"] = o.image; - item["visible_in_fog"] = o.visible_in_fog; - - // Optional keys - item["id"].write_if_not_empty(o.id); - item["name"].write_if_not_empty(o.name); - item["team_name"].write_if_not_empty(o.team_name); - item["halo"].write_if_not_empty(o.halo); + // Optional keys + item["id"].write_if_not_empty(o.id); + item["name"].write_if_not_empty(o.name); + item["team_name"].write_if_not_empty(o.team_name); + item["halo"].write_if_not_empty(o.halo); + } } for(const music_map::value_type& track : music_tracks_) { diff --git a/src/editor/map/map_context.hpp b/src/editor/map/map_context.hpp index 7d461208ad3e..74dbecc8fe31 100644 --- a/src/editor/map/map_context.hpp +++ b/src/editor/map/map_context.hpp @@ -25,6 +25,8 @@ #include "overlay.hpp" #include "display_context.hpp" +#include + namespace editor { struct editor_team_info { @@ -502,7 +504,7 @@ class map_context : public display_context typedef std::map music_map; music_map music_tracks_; - typedef std::multimap overlay_map; + typedef std::map> overlay_map; overlay_map overlays_; public: