Skip to content

Commit

Permalink
use ptr to impl for gamemap in game_board, avoiding map.h include
Browse files Browse the repository at this point in the history
unit_map is modified in many places that don't normally include
map.hpp, so to avoid doing harm by adding this class, I am making
it hold a scoped pointer to the gamemap instead of an actual
gamemap. This results in very few changes.

- The implementation of game_board has to use the pointer.
- game_board must use copy and swap idiom
- lua get terrain function must pass strings to the game_board,
  not enums, and we parse them as std::strings in game_board
  instead of as c strings in lua api (which was a bit gross anyhow)
  • Loading branch information
cbeck88 committed Jun 11, 2014
1 parent 148d42e commit e4eb0a3
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 39 deletions.
61 changes: 46 additions & 15 deletions src/game_board.cpp
Expand Up @@ -16,6 +16,7 @@
#include "game_board.hpp"
#include "game_preferences.hpp"
#include "log.hpp"
#include "map.hpp"
#include "unit.hpp"

#include "utils/foreach.tpp"
Expand All @@ -28,6 +29,27 @@ static lg::log_domain log_engine("enginerefac");
#define WRN_RG LOG_STREAM(warn, log_engine)
#define ERR_RG LOG_STREAM(err, log_engine)

game_board::game_board(const config & game_config, const config & level) : teams_(), map_(new gamemap(game_config, level)), units_() {}

game_board::game_board(const game_board & other) : teams_(other.teams_), map_(new gamemap(*(other.map_))), units_(other.units_) {}

game_board::~game_board() {}


//TODO: Fix this so that we swap pointers to maps, and also fix replace_map to use scoped_ptr::reset.
// However, then anytime gameboard is overwritten, resources::gamemap must be updated. So might want to
// just get rid of resources::gamemap and replace with resources::gameboard->map() at that point.
void swap(game_board & one, game_board & other) {
std::swap(one.teams_, other.teams_);
std::swap(one.units_, other.units_);
one.map_.swap(other.map_);
}

game_board & game_board::operator= (game_board other)
{
swap(*this, other);
return(*this);
}

void game_board::new_turn(int player_num) {
BOOST_FOREACH (unit & i, units_) {
Expand Down Expand Up @@ -64,18 +86,18 @@ void game_board::all_survivors_to_recall() {
unit_map::iterator game_board::find_visible_unit(const map_location &loc,
const team& current_team, bool see_all)
{
if (!map_.on_board(loc)) return units_.end();
if (!map_->on_board(loc)) return units_.end();
unit_map::iterator u = units_.find(loc);
if (!u.valid() || !u->is_visible_to_team(current_team, map_, see_all))
if (!u.valid() || !u->is_visible_to_team(current_team, *map_, see_all))
return units_.end();
return u;
}

bool game_board::has_visible_unit(const map_location & loc, const team& current_team, bool see_all)
{
if (!map_.on_board(loc)) return false;
if (!map_->on_board(loc)) return false;
unit_map::iterator u = units_.find(loc);
if (!u.valid() || !u->is_visible_to_team(current_team, map_, see_all))
if (!u.valid() || !u->is_visible_to_team(current_team, *map_, see_all))
return false;
return true;
}
Expand Down Expand Up @@ -134,7 +156,7 @@ boost::optional<std::string> game_board::replace_map(const gamemap & newmap) {

/* Remember the locations where a village is owned by a side. */
std::map<map_location, int> villages;
FOREACH(const AUTO& village, map_.villages()) {
FOREACH(const AUTO& village, map_->villages()) {
const int owner = village_owner(village);
if(owner != -1) {
villages[village] = owner;
Expand All @@ -159,19 +181,28 @@ boost::optional<std::string> game_board::replace_map(const gamemap & newmap) {
}
}

map_ = newmap;
*map_ = newmap;
return ret;
}



void game_board::overlay_map(const gamemap & mask_map, const config & cfg, map_location loc, bool border) {
map_.overlay(mask_map, cfg, loc.x, loc.y, border);
map_->overlay(mask_map, cfg, loc.x, loc.y, border);
}

bool game_board::change_terrain(const map_location &loc, const t_translation::t_terrain &t,
gamemap::tmerge_mode mode, bool replace_if_failed)
bool game_board::change_terrain(const map_location &loc, const std::string &t_str,
const std::string & mode_str, bool replace_if_failed)
{
//Code internalized from the implementation in lua.cpp
t_translation::t_terrain terrain = t_translation::read_terrain_code(t_str);
if (terrain == t_translation::NONE_TERRAIN) return false;

gamemap::tmerge_mode mode = gamemap::BOTH;

if (mode_str == "base") mode = gamemap::BASE;
else if (mode_str == "overlay") mode = gamemap::OVERLAY;

/*
* When a hex changes from a village terrain to a non-village terrain, and
* a team owned that village it loses that village. When a hex changes from
Expand All @@ -183,20 +214,20 @@ bool game_board::change_terrain(const map_location &loc, const t_translation::t_
*/

t_translation::t_terrain
old_t = map_.get_terrain(loc),
new_t = map_.merge_terrains(old_t, t, mode, replace_if_failed);
old_t = map_->get_terrain(loc),
new_t = map_->merge_terrains(old_t, terrain, mode, replace_if_failed);
if (new_t == t_translation::NONE_TERRAIN) return false;
preferences::encountered_terrains().insert(new_t);

if (map_.is_village(old_t) && !map_.is_village(new_t)) {
if (map_->is_village(old_t) && !map_->is_village(new_t)) {
int owner = village_owner(loc);
if (owner != -1)
teams_[owner].lose_village(loc);
}

map_.set_terrain(loc, new_t);
map_->set_terrain(loc, new_t);

BOOST_FOREACH(const t_translation::t_terrain &ut, map_.underlying_union_terrain(loc)) {
BOOST_FOREACH(const t_translation::t_terrain &ut, map_->underlying_union_terrain(loc)) {
preferences::encountered_terrains().insert(ut);
}
return true;
Expand Down Expand Up @@ -231,7 +262,7 @@ void game_board::write_config(config & cfg) const {
}

//write the map
cfg["map_data"] = map_.write();
cfg["map_data"] = map_->write();
}

temporary_unit_placer::temporary_unit_placer(unit_map& m, const map_location& loc, unit& u)
Expand Down
25 changes: 18 additions & 7 deletions src/game_board.hpp
Expand Up @@ -18,14 +18,15 @@
#include "global.hpp"

#include "display_context.hpp"
#include "map.hpp"
#include "team.hpp"
#include "unit_map.hpp"

#include <boost/optional.hpp>
#include <boost/scoped_ptr.hpp>
#include <vector>

class config;
class gamemap;

namespace events {
class mouse_handler;
Expand All @@ -51,7 +52,7 @@ class game_board : public display_context {

std::vector<team> teams_;

gamemap map_;
boost::scoped_ptr<gamemap> map_;
unit_map units_;

//TODO: Remove these when we have refactored enough to make it possible.
Expand Down Expand Up @@ -85,13 +86,20 @@ class game_board : public display_context {

// Constructors, trivial dtor, and const accessors

game_board(const config & game_config, const config & level) : teams_(), map_(game_config, level), units_() {}
virtual ~game_board() {}
game_board(const config & game_config, const config & level);
virtual ~game_board();

virtual const std::vector<team> & teams() const { return teams_; }
virtual const gamemap & map() const { return map_; }
virtual const gamemap & map() const { return *map_; }
virtual const unit_map & units() const { return units_; }

// Copy and swap idiom, because we have a scoped pointer.

game_board(const game_board & other);
game_board & operator= (game_board other);

friend void swap(game_board & one, game_board & other);

// Saving

void write_config(config & cfg) const;
Expand All @@ -115,8 +123,8 @@ class game_board : public display_context {
boost::optional<std::string> replace_map (const gamemap & r);
void overlay_map (const gamemap & o, const config & cfg, map_location loc, bool border);

bool change_terrain(const map_location &loc, const t_translation::t_terrain &t,
gamemap::tmerge_mode mode, bool replace_if_failed); //used only by lua
bool change_terrain(const map_location &loc, const std::string &t,
const std::string & mode, bool replace_if_failed); //used only by lua

// Global accessor from unit.hpp

Expand All @@ -132,6 +140,9 @@ class game_board : public display_context {
unit_map::iterator find_unit(const map_location & loc) { return units_.find(loc); }
};

void swap(game_board & one, game_board & other);


/**
* This object is used to temporary place a unit in the unit map, swapping out
* any unit that is already there. On destruction, it restores the unit map to
Expand Down
10 changes: 5 additions & 5 deletions src/play_controller.cpp
Expand Up @@ -227,7 +227,7 @@ void play_controller::init(CVideo& video){
}
}
team_builder_ptr tb_ptr = gamedata_.create_team_builder(side,
save_id, gameboard_.teams_, level_, gameboard_.map_, gameboard_.units_, gamestate_.replay_start());
save_id, gameboard_.teams_, level_, *gameboard_.map_, gameboard_.units_, gamestate_.replay_start());
++team_num;
gamedata_.build_team_stage_one(tb_ptr);
team_builders.push_back(tb_ptr);
Expand Down Expand Up @@ -366,14 +366,14 @@ void play_controller::place_sides_in_preferred_locations()
{
std::vector<placing_info> placings;

int num_pos = gameboard_.map_.num_valid_starting_positions();
int num_pos = gameboard_.map().num_valid_starting_positions();

int side_num = 1;
BOOST_FOREACH(const config &side, level_.child_range("side"))
{
for(int p = 1; p <= num_pos; ++p) {
const map_location& pos = gameboard_.map_.starting_position(p);
int score = placing_score(side, gameboard_.map_, pos);
const map_location& pos = gameboard_.map().starting_position(p);
int score = placing_score(side, gameboard_.map(), pos);
placing_info obj;
obj.side = side_num;
obj.score = score;
Expand All @@ -391,7 +391,7 @@ void play_controller::place_sides_in_preferred_locations()
if(placed.count(i->side) == 0 && positions_taken.count(i->pos) == 0) {
placed.insert(i->side);
positions_taken.insert(i->pos);
gameboard_.map_.set_starting_position(i->side,i->pos);
gameboard_.map_->set_starting_position(i->side,i->pos);
LOG_NG << "placing side " << i->side << " at " << i->pos << std::endl;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/play_controller.hpp
Expand Up @@ -140,7 +140,7 @@ class play_controller : public controller_base, public events::observer, public
return gameboard_.teams_;
}
const gamemap& get_map_const() const{
return gameboard_.map_;
return gameboard_.map();
}
const tod_manager& get_tod_manager_const() const{
return tod_manager_;
Expand Down
8 changes: 4 additions & 4 deletions src/playsingle_controller.cpp
Expand Up @@ -100,9 +100,9 @@ void playsingle_controller::init_gui(){
play_controller::init_gui();

if(first_human_team_ != -1) {
gui_->scroll_to_tile(gameboard_.map_.starting_position(first_human_team_ + 1), game_display::WARP);
gui_->scroll_to_tile(gameboard_.map().starting_position(first_human_team_ + 1), game_display::WARP);
}
gui_->scroll_to_tile(gameboard_.map_.starting_position(1), game_display::WARP);
gui_->scroll_to_tile(gameboard_.map().starting_position(1), game_display::WARP);

update_locker lock_display(gui_->video(),recorder.is_skipping());
events::raise_draw_event();
Expand Down Expand Up @@ -1072,15 +1072,15 @@ bool playsingle_controller::can_execute_command(const hotkey::hotkey_command& cm
case hotkey::HOTKEY_CREATE_UNIT:
case hotkey::HOTKEY_CHANGE_SIDE:
case hotkey::HOTKEY_KILL_UNIT:
return !events::commands_disabled && game_config::debug && gameboard_.map_.on_board(mouse_handler_.get_last_hex());
return !events::commands_disabled && game_config::debug && gameboard_.map().on_board(mouse_handler_.get_last_hex());

case hotkey::HOTKEY_CLEAR_LABELS:
res = !is_observer();
break;
case hotkey::HOTKEY_LABEL_TEAM_TERRAIN:
case hotkey::HOTKEY_LABEL_TERRAIN: {
const terrain_label *label = resources::screen->labels().get_label(mouse_handler_.get_last_hex());
res = !events::commands_disabled && gameboard_.map_.on_board(mouse_handler_.get_last_hex())
res = !events::commands_disabled && gameboard_.map().on_board(mouse_handler_.get_last_hex())
&& !gui_->shrouded(mouse_handler_.get_last_hex())
&& !is_observer()
&& (!label || !label->immutable());
Expand Down
11 changes: 4 additions & 7 deletions src/scripting/lua.cpp
Expand Up @@ -1271,24 +1271,21 @@ static int intf_set_terrain(lua_State *L)
{
int x = luaL_checkint(L, 1);
int y = luaL_checkint(L, 2);
t_translation::t_terrain terrain = t_translation::read_terrain_code(luaL_checkstring(L, 3));
if (terrain == t_translation::NONE_TERRAIN) return 0;
std::string t_str(luaL_checkstring(L, 3));

gamemap::tmerge_mode mode = gamemap::BOTH;
std::string mode_str = "both";
bool replace_if_failed = false;
if (!lua_isnone(L, 4)) {
if (!lua_isnil(L, 4)) {
const char* const layer = luaL_checkstring(L, 4);
if (strcmp(layer, "base") == 0) mode = gamemap::BASE;
else if (strcmp(layer, "overlay") == 0) mode = gamemap::OVERLAY;
mode_str = luaL_checkstring(L, 4);
}

if(!lua_isnoneornil(L, 5)) {
replace_if_failed = luaW_toboolean(L, 5);
}
}

bool result = resources::gameboard->change_terrain(map_location(x - 1, y - 1), terrain, mode, replace_if_failed);
bool result = resources::gameboard->change_terrain(map_location(x - 1, y - 1), t_str, mode_str, replace_if_failed);
if (result) {
resources::screen->recalculate_minimap();
resources::screen->invalidate_all();
Expand Down

0 comments on commit e4eb0a3

Please sign in to comment.