Split the rect_of_hexes struct into its own file

And cleaned up it a bit. Made use of std::array and gave it a default ctor using
the values from display::hexes_under_rect.
This commit is contained in:
Charles Dang 2018-03-24 13:22:25 +11:00
parent c76bef8bb8
commit 5ece7ac5b7
6 changed files with 117 additions and 86 deletions

View file

@ -3875,6 +3875,7 @@
<ClInclude Include="..\..\src\language.hpp" />
<ClInclude Include="..\..\src\lua_jailbreak_exception.hpp" />
<ClInclude Include="..\..\src\map\exception.hpp" />
<ClInclude Include="..\..\src\map\hex_rect.hpp" />
<ClInclude Include="..\..\src\map\label.hpp" />
<ClInclude Include="..\..\src\map\location.hpp" />
<ClInclude Include="..\..\src\map\map.hpp" />

View file

@ -3006,6 +3006,9 @@
<ClInclude Include="..\..\src\preferences\lobby.hpp">
<Filter>Preferences</Filter>
</ClInclude>
<ClInclude Include="..\..\src\map\hex_rect.hpp">
<Filter>Map</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\src\tests\test_sdl_utils.hpp">

View file

@ -572,41 +572,11 @@ const map_location display::pixel_position_to_hex(int x, int y) const
return map_location(x_base + x_modifier - offset, y_base + y_modifier - offset);
}
display::rect_of_hexes::iterator& display::rect_of_hexes::iterator::operator++()
{
if(loc_.y < rect_.bottom[loc_.x & 1])
++loc_.y;
else {
++loc_.x;
loc_.y = rect_.top[loc_.x & 1];
}
return *this;
}
// begin is top left, and end is after bottom right
display::rect_of_hexes::iterator display::rect_of_hexes::begin() const
{
return iterator(map_location(left, top[left & 1]), *this);
}
display::rect_of_hexes::iterator display::rect_of_hexes::end() const
{
return iterator(map_location(right + 1, top[(right + 1) & 1]), *this);
}
const display::rect_of_hexes display::hexes_under_rect(const SDL_Rect& r) const
const rect_of_hexes display::hexes_under_rect(const SDL_Rect& r) const
{
rect_of_hexes res;
if(r.w <= 0 || r.h <= 0) {
// empty rect, return dummy values giving begin=end
res.left = 0;
res.right = -1; // end is right + 1
res.top[0] = 0;
res.top[1] = 0;
res.bottom[0] = 0;
res.bottom[1] = 0;
return res;
}

View file

@ -57,6 +57,7 @@ class manager;
#include "font/standard_colors.hpp"
#include "image.hpp" //only needed for enums (!)
#include "key.hpp"
#include "map/hex_rect.hpp"
#include "overlay.hpp"
#include "sdl/rect.hpp"
#include "sdl/surface.hpp"
@ -378,60 +379,6 @@ public:
*/
SDL_Point get_loc_drawing_origin(const map_location& loc) const;
/**
* Rectangular area of hexes, allowing to decide how the top and bottom
* edges handles the vertical shift for each parity of the x coordinate
*/
struct rect_of_hexes
{
int left;
int right;
int top[2]; // for even and odd values of x, respectively
int bottom[2];
/** very simple iterator to walk into the rect_of_hexes */
struct iterator
{
iterator(const map_location& loc, const rect_of_hexes& rect)
: loc_(loc)
, rect_(rect)
{
}
/** increment y first, then when reaching bottom, increment x */
iterator& operator++();
bool operator==(const iterator& that) const
{
return that.loc_ == loc_;
}
bool operator!=(const iterator& that) const
{
return that.loc_ != loc_;
}
const map_location& operator*() const
{
return loc_;
}
typedef std::forward_iterator_tag iterator_category;
typedef map_location value_type;
typedef int difference_type;
typedef const map_location* pointer;
typedef const map_location& reference;
private:
map_location loc_;
const rect_of_hexes& rect_;
};
typedef iterator const_iterator;
iterator begin() const;
iterator end() const;
};
/** Return the rectangular area of hexes overlapped by r (r is in screen coordinates) */
const rect_of_hexes hexes_under_rect(const SDL_Rect& r) const;

109
src/map/hex_rect.hpp Normal file
View file

@ -0,0 +1,109 @@
/*
Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#pragma once
#include "map/location.hpp"
#include <array>
#include <iterator>
/**
* Rectangular area of hexes.
*
* Allows decising how the top and bottom edges handles the vertical shift
* for parity with the x coordinate.
*
* @todo Improve this documentation because I'm not sure best how to describe
* the function of this class.
*
* -- vultraz, 2018-03-24
*/
struct rect_of_hexes
{
/** Default ctor. Will evaluate as begin() == end(). */
rect_of_hexes()
: left(0)
, right(-1) // end is right + 1
, top{0,0}
, bottom{0,0}
{
}
int left;
int right;
std::array<int, 2> top; // for even and odd values of x, respectively
std::array<int, 2> bottom;
/** Very simple iterator to walk into the rect_of_hexes */
struct iterator
{
iterator(const map_location& loc, const rect_of_hexes& rect)
: loc_(loc)
, rect_(rect)
{
}
/** Increment y first, then when reaching bottom, increment x. */
iterator& operator++()
{
if(loc_.y < rect_.bottom[loc_.x & 1]) {
++loc_.y;
} else {
++loc_.x;
loc_.y = rect_.top[loc_.x & 1];
}
return *this;
}
bool operator==(const iterator& that) const
{
return that.loc_ == loc_;
}
bool operator!=(const iterator& that) const
{
return that.loc_ != loc_;
}
const map_location& operator*() const
{
return loc_;
}
using iterator_category = std::forward_iterator_tag;
using value_type = map_location;
using difference_type = int;
using pointer = const map_location*;
using reference = const map_location&;
private:
map_location loc_;
const rect_of_hexes& rect_;
};
using const_iterator = iterator;
iterator begin() const
{
return iterator(map_location(left, top[left & 1]), *this);
}
iterator end() const
{
return iterator(map_location(right + 1, top[(right + 1) & 1]), *this);
}
};

View file

@ -17,6 +17,7 @@
#include "color.hpp"
#include "game_display.hpp"
#include "log.hpp"
#include "map/hex_rect.hpp"
#include "sdl/render_utils.hpp"
#include "sound.hpp"
@ -786,7 +787,7 @@ std::set<map_location> unit_frame::get_overlaped_hex(const int frame_time, const
// Check if our underlying hexes are invalidated. If we need to update ourselves because we changed,
// invalidate our hexes and return whether or not was successful.
const SDL_Rect r {my_x, my_y, w, h};
display::rect_of_hexes underlying_hex = disp->hexes_under_rect(r);
rect_of_hexes underlying_hex = disp->hexes_under_rect(r);
result.insert(src);
result.insert(underlying_hex.begin(), underlying_hex.end());