Skip to content

Commit

Permalink
Changed data type of display::get_overlays()
Browse files Browse the repository at this point in the history
`std::multimap` is a poor fit after commit
082aa2a because `std::multimap` doesn't
allow reordering of elements assigned to the same key.
  • Loading branch information
jyrkive committed Oct 23, 2018
1 parent c701430 commit fa12518
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 87 deletions.
111 changes: 40 additions & 71 deletions src/display.cpp
Expand Up @@ -53,6 +53,7 @@

#include <SDL_image.h>

#include <algorithm>
#include <array>
#include <cmath>
#include <iomanip>
Expand Down Expand Up @@ -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);
}
}
}
}
Expand All @@ -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<overlay>& 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<Itor,Itor> 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<Itor,Itor> 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<overlay>& 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::manager> wb, reports & reports_object, const config& theme_cfg, const config& level, bool auto_join) :
Expand Down Expand Up @@ -2603,28 +2574,26 @@ void display::draw_hex(const map_location& loc) {
}

if(!shrouded(loc)) {
typedef overlay_map::const_iterator Itor;
std::pair<Itor,Itor> 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<std::string>& current_team_names = utils::split(current_team_name);
const std::vector<std::string>& 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<overlay>& 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<std::string>& current_team_names = utils::split(current_team_name);
const std::vector<std::string>& 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);
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/display.hpp
Expand Up @@ -71,6 +71,7 @@ namespace wb {
#include <list>
#include <map>
#include <memory>
#include <vector>

class gamemap;

Expand Down Expand Up @@ -1026,7 +1027,7 @@ class display : public video2::draw_layering
bool reach_map_changed_;
void process_reachmap_changes();

typedef std::multimap<map_location, overlay> overlay_map;
typedef std::map<map_location, std::vector<overlay>> overlay_map;

virtual overlay_map& get_overlays() = 0;

Expand Down
28 changes: 14 additions & 14 deletions src/editor/map/map_context.cpp
Expand Up @@ -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")) {
Expand Down Expand Up @@ -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_) {
Expand Down
4 changes: 3 additions & 1 deletion src/editor/map/map_context.hpp
Expand Up @@ -25,6 +25,8 @@
#include "overlay.hpp"
#include "display_context.hpp"

#include <vector>

namespace editor {

struct editor_team_info {
Expand Down Expand Up @@ -502,7 +504,7 @@ class map_context : public display_context
typedef std::map<std::string, sound::music_track> music_map;
music_map music_tracks_;

typedef std::multimap<map_location, overlay> overlay_map;
typedef std::map<map_location, std::vector<overlay>> overlay_map;
overlay_map overlays_;

public:
Expand Down

0 comments on commit fa12518

Please sign in to comment.