From 1ec273c88265cc3e00b79789225da7d512b9410a Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Tue, 3 Jun 2014 12:08:26 -0400 Subject: [PATCH] move temporary unit movers to game_board, adapt slightly. --- src/ai/formula/function_table.cpp | 1 + src/game_board.cpp | 110 ++++++++++++++++++++++++++++++ src/game_board.hpp | 97 ++++++++++++++++++++++++++ src/unit.cpp | 74 -------------------- src/unit.hpp | 55 --------------- src/whiteboard/action.cpp | 1 + src/whiteboard/attack.cpp | 1 + src/whiteboard/highlighter.cpp | 1 + src/whiteboard/manager.cpp | 1 + src/whiteboard/mapbuilder.cpp | 1 + src/whiteboard/mapbuilder.hpp | 2 + src/whiteboard/move.cpp | 3 + src/whiteboard/move.hpp | 2 +- src/whiteboard/typedefs.hpp | 1 + 14 files changed, 220 insertions(+), 130 deletions(-) diff --git a/src/ai/formula/function_table.cpp b/src/ai/formula/function_table.cpp index 1fd9881aa3d5..5eda6d84a548 100644 --- a/src/ai/formula/function_table.cpp +++ b/src/ai/formula/function_table.cpp @@ -24,6 +24,7 @@ #include "../../attack_prediction.hpp" #include "../../filesystem.hpp" +#include "../../game_board.hpp" #include "../../game_display.hpp" #include "../../log.hpp" #include "../../map_label.hpp" diff --git a/src/game_board.cpp b/src/game_board.cpp index 16613fa2f202..a65683dbb855 100644 --- a/src/game_board.cpp +++ b/src/game_board.cpp @@ -214,3 +214,113 @@ void game_board::write_config(config & cfg) const { //write the map cfg["map_data"] = map_.write(); } + +temporary_unit_placer::temporary_unit_placer(unit_map& m, const map_location& loc, unit& u) + : m_(m), loc_(loc), temp_(m_.extract(loc)) +{ + u.clone(); + m_.add(loc, u); +} + +temporary_unit_placer::temporary_unit_placer(game_board& b, const map_location& loc, unit& u) + : m_(b.units_), loc_(loc), temp_(m_.extract(loc)) +{ + u.clone(); + m_.add(loc, u); +} + +temporary_unit_placer::~temporary_unit_placer() +{ + m_.erase(loc_); + if(temp_) { + m_.insert(temp_); + } +} + +temporary_unit_remover::temporary_unit_remover(unit_map& m, const map_location& loc) + : m_(m), loc_(loc), temp_(m_.extract(loc)) +{ +} + +temporary_unit_remover::temporary_unit_remover(game_board& b, const map_location& loc) + : m_(b.units_), loc_(loc), temp_(m_.extract(loc)) +{ +} + +temporary_unit_remover::~temporary_unit_remover() +{ + if(temp_) { + m_.insert(temp_); + } +} + +/** + * Constructor + * This version will change the unit's current movement to @a new_moves while + * the unit is moved (and restored to its previous value upon this object's + * destruction). + */ +temporary_unit_mover::temporary_unit_mover(unit_map& m, const map_location& src, + const map_location& dst, int new_moves) + : m_(m), src_(src), dst_(dst), old_moves_(-1), + temp_(src == dst ? NULL : m_.extract(dst)) +{ + std::pair move_result = m_.move(src_, dst_); + + // Set the movement. + if ( move_result.second ) + { + old_moves_ = move_result.first->movement_left(true); + move_result.first->set_movement(new_moves); + } +} + +temporary_unit_mover::temporary_unit_mover(game_board& b, const map_location& src, + const map_location& dst, int new_moves) + : m_(b.units_), src_(src), dst_(dst), old_moves_(-1), + temp_(src == dst ? NULL : m_.extract(dst)) +{ + std::pair move_result = m_.move(src_, dst_); + + // Set the movement. + if ( move_result.second ) + { + old_moves_ = move_result.first->movement_left(true); + move_result.first->set_movement(new_moves); + } +} + +/** + * Constructor + * This version does not change (nor restore) the unit's movement. + */ +temporary_unit_mover::temporary_unit_mover(unit_map& m, const map_location& src, + const map_location& dst) + : m_(m), src_(src), dst_(dst), old_moves_(-1), + temp_(src == dst ? NULL : m_.extract(dst)) +{ + m_.move(src_, dst_); +} + +temporary_unit_mover::temporary_unit_mover(game_board& b, const map_location& src, + const map_location& dst) + : m_(b.units_), src_(src), dst_(dst), old_moves_(-1), + temp_(src == dst ? NULL : m_.extract(dst)) +{ + m_.move(src_, dst_); +} + +temporary_unit_mover::~temporary_unit_mover() +{ + std::pair move_result = m_.move(dst_, src_); + + // Restore the movement? + if ( move_result.second && old_moves_ >= 0 ) + move_result.first->set_movement(old_moves_); + + // Restore the extracted unit? + if(temp_) { + m_.insert(temp_); + } +} + diff --git a/src/game_board.hpp b/src/game_board.hpp index bff2305fefa0..b55bc8c52b3e 100644 --- a/src/game_board.hpp +++ b/src/game_board.hpp @@ -30,6 +30,20 @@ namespace events { class mouse_handler; } +/** + * + * Game board class. + * + * The purpose of this class is to encapsulate some of the core game logic, including the unit map, + * the list of teams, and the game map. + * + * This should eventually become part of the game state object IMO, which should be a child of play_controller. + * + * I also intend to move the pathfinding module to be housed within this class -- this way, we can implement a + * sound pathfinding data structure to speed up path computations for AI, without having to make "update event" + * code at all points in the engine which modify the relevant data. + * + **/ class game_board { @@ -44,6 +58,24 @@ class game_board { friend class playsingle_controller; friend class playmp_controller; friend class events::mouse_handler; + + /** + * Temporary unit move structs: + * + * Probably don't remove these friends, this is actually fairly useful. These structs are used by: + * - AI + * - Whiteboard + * - I think certain wml actions + * For AI, the ai wants to move two units next to eachother so it can ask for attack calculations. This should not trigger + * pathfinding modifications, so the version that directly changes the unit map is probably preferable, although it should be + * refactored. + * For whiteboard and wml actions, we generally do want pathfinding to be updated, so use the game_board constructors which I + * have added to these structs instead. + * + **/ + friend struct temporary_unit_placer; + friend struct temporary_unit_mover; + friend struct temporary_unit_remover; public: @@ -85,4 +117,69 @@ class game_board { unit* get_visible_unit(const map_location &loc, const team ¤t_team, bool see_all = false); //TODO: can this not return a pointer? }; +/** + * 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 + * its original. + */ +struct temporary_unit_placer +{ + temporary_unit_placer(unit_map& m, const map_location& loc, unit& u); + temporary_unit_placer(game_board& m, const map_location& loc, unit& u); + virtual ~temporary_unit_placer(); + +private: + unit_map& m_; + const map_location loc_; + unit *temp_; +}; + +// Begin Temporary Unit Move Structs +// TODO: Fix up the implementations which use game_board + +/** + * This object is used to temporary remove a unit from the unit map. + * On destruction, it restores the unit map to its original. + * unit_map iterators to this unit must not be accessed while the unit is temporarily + * removed, otherwise a collision will happen when trying to reinsert the unit. + */ +struct temporary_unit_remover +{ + temporary_unit_remover(unit_map& m, const map_location& loc); + temporary_unit_remover(game_board& m, const map_location& loc); + virtual ~temporary_unit_remover(); + +private: + unit_map& m_; + const map_location loc_; + unit *temp_; +}; + + +/** + * This object is used to temporary move a unit in the unit map, swapping out + * any unit that is already there. On destruction, it restores the unit map to + * its original. + */ +struct temporary_unit_mover +{ + temporary_unit_mover(unit_map& m, const map_location& src, + const map_location& dst, int new_moves); + temporary_unit_mover(unit_map& m, const map_location& src, + const map_location& dst); + temporary_unit_mover(game_board& b, const map_location& src, + const map_location& dst, int new_moves); + temporary_unit_mover(game_board& b, const map_location& src, + const map_location& dst); + virtual ~temporary_unit_mover(); + +private: + unit_map& m_; + const map_location src_; + const map_location dst_; + int old_moves_; + unit *temp_; +}; + + #endif diff --git a/src/unit.cpp b/src/unit.cpp index fbbe28906fe5..9c69d9baedde 100644 --- a/src/unit.cpp +++ b/src/unit.cpp @@ -3062,80 +3062,6 @@ team_data calculate_team_data(const team& tm, int side) return res; } -temporary_unit_placer::temporary_unit_placer(unit_map& m, const map_location& loc, unit& u) - : m_(m), loc_(loc), temp_(m.extract(loc)) -{ - u.clone(); - m.add(loc, u); -} - -temporary_unit_placer::~temporary_unit_placer() -{ - m_.erase(loc_); - if(temp_) { - m_.insert(temp_); - } -} - -temporary_unit_remover::temporary_unit_remover(unit_map& m, const map_location& loc) - : m_(m), loc_(loc), temp_(m.extract(loc)) -{ -} - -temporary_unit_remover::~temporary_unit_remover() -{ - if(temp_) { - m_.insert(temp_); - } -} - -/** - * Constructor - * This version will change the unit's current movement to @a new_moves while - * the unit is moved (and restored to its previous value upon this object's - * destruction). - */ -temporary_unit_mover::temporary_unit_mover(unit_map& m, const map_location& src, - const map_location& dst, int new_moves) - : m_(m), src_(src), dst_(dst), old_moves_(-1), - temp_(src == dst ? NULL : m.extract(dst)) -{ - std::pair move_result = m.move(src_, dst_); - - // Set the movement. - if ( move_result.second ) - { - old_moves_ = move_result.first->movement_left(true); - move_result.first->set_movement(new_moves); - } -} - -/** - * Constructor - * This version does not change (nor restore) the unit's movement. - */ -temporary_unit_mover::temporary_unit_mover(unit_map& m, const map_location& src, - const map_location& dst) - : m_(m), src_(src), dst_(dst), old_moves_(-1), - temp_(src == dst ? NULL : m.extract(dst)) -{ - m.move(src_, dst_); -} - -temporary_unit_mover::~temporary_unit_mover() -{ - std::pair move_result = m_.move(dst_, src_); - - // Restore the movement? - if ( move_result.second && old_moves_ >= 0 ) - move_result.first->set_movement(old_moves_); - - // Restore the extracted unit? - if(temp_) { - m_.insert(temp_); - } -} - std::string unit::TC_image_mods() const{ std::stringstream modifier; if(!flag_rgb_.empty()){ diff --git a/src/unit.hpp b/src/unit.hpp index b5931e868ab9..d7e9d0139813 100644 --- a/src/unit.hpp +++ b/src/unit.hpp @@ -596,61 +596,6 @@ struct team_data team_data calculate_team_data(const class team& tm, int side); -/** - * 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 - * its original. - */ -struct temporary_unit_placer -{ - temporary_unit_placer(unit_map& m, const map_location& loc, unit& u); - virtual ~temporary_unit_placer(); - -private: - unit_map& m_; - const map_location loc_; - unit *temp_; -}; - -/** - * This object is used to temporary remove a unit from the unit map. - * On destruction, it restores the unit map to its original. - * unit_map iterators to this unit must not be accessed while the unit is temporarily - * removed, otherwise a collision will happen when trying to reinsert the unit. - */ -struct temporary_unit_remover -{ - temporary_unit_remover(unit_map& m, const map_location& loc); - virtual ~temporary_unit_remover(); - -private: - unit_map& m_; - const map_location loc_; - unit *temp_; -}; - - -/** - * This object is used to temporary move a unit in the unit map, swapping out - * any unit that is already there. On destruction, it restores the unit map to - * its original. - */ -struct temporary_unit_mover -{ - temporary_unit_mover(unit_map& m, const map_location& src, - const map_location& dst, int new_moves); - temporary_unit_mover(unit_map& m, const map_location& src, - const map_location& dst); - virtual ~temporary_unit_mover(); - -private: - unit_map& m_; - const map_location src_; - const map_location dst_; - int old_moves_; - unit *temp_; -}; - /** * Gets a checksum for a unit. * diff --git a/src/whiteboard/action.cpp b/src/whiteboard/action.cpp index 1885b1c40211..f04337c4e9cd 100644 --- a/src/whiteboard/action.cpp +++ b/src/whiteboard/action.cpp @@ -23,6 +23,7 @@ #include "recall.hpp" #include "suppose_dead.hpp" +#include "game_board.hpp" #include "resources.hpp" #include "team.hpp" #include "unit.hpp" diff --git a/src/whiteboard/attack.cpp b/src/whiteboard/attack.cpp index ba20152def19..b5c13a8e6f9a 100644 --- a/src/whiteboard/attack.cpp +++ b/src/whiteboard/attack.cpp @@ -22,6 +22,7 @@ #include "utility.hpp" #include "arrow.hpp" +#include "game_board.hpp" #include "play_controller.hpp" #include "resources.hpp" #include "unit.hpp" diff --git a/src/whiteboard/highlighter.cpp b/src/whiteboard/highlighter.cpp index 8a62a7738ab6..b995704024d4 100644 --- a/src/whiteboard/highlighter.cpp +++ b/src/whiteboard/highlighter.cpp @@ -34,6 +34,7 @@ #include "utility.hpp" #include "arrow.hpp" +#include "game_board.hpp" #include "play_controller.hpp" #include "resources.hpp" #include "unit_map.hpp" diff --git a/src/whiteboard/manager.cpp b/src/whiteboard/manager.cpp index 4bee655a6e25..bf31ffcb5743 100644 --- a/src/whiteboard/manager.cpp +++ b/src/whiteboard/manager.cpp @@ -33,6 +33,7 @@ #include "arrow.hpp" #include "chat_events.hpp" #include "formula_string_utils.hpp" +#include "game_board.hpp" #include "game_preferences.hpp" #include "gettext.hpp" #include "gui/dialogs/simple_item_selector.hpp" diff --git a/src/whiteboard/mapbuilder.cpp b/src/whiteboard/mapbuilder.cpp index 16bcd9d57f97..110f2e59ac0d 100644 --- a/src/whiteboard/mapbuilder.cpp +++ b/src/whiteboard/mapbuilder.cpp @@ -23,6 +23,7 @@ #include "side_actions.hpp" #include "utility.hpp" +#include "game_board.hpp" #include "play_controller.hpp" #include "resources.hpp" #include "unit.hpp" diff --git a/src/whiteboard/mapbuilder.hpp b/src/whiteboard/mapbuilder.hpp index 61bede662400..98f428fc79b3 100644 --- a/src/whiteboard/mapbuilder.hpp +++ b/src/whiteboard/mapbuilder.hpp @@ -26,6 +26,8 @@ struct unit_movement_resetter; +struct temporary_unit_remover; + namespace wb { diff --git a/src/whiteboard/move.cpp b/src/whiteboard/move.cpp index 833ff294bcf4..1a936f4a27e3 100644 --- a/src/whiteboard/move.cpp +++ b/src/whiteboard/move.cpp @@ -25,6 +25,7 @@ #include "arrow.hpp" #include "config.hpp" +#include "game_board.hpp" #include "game_end_exceptions.hpp" #include "mouse_events.hpp" #include "play_controller.hpp" @@ -187,6 +188,8 @@ void move::init() } } +move::~move(){} + void move::accept(visitor& v) { v.visit(shared_from_this()); diff --git a/src/whiteboard/move.hpp b/src/whiteboard/move.hpp index 85694d0018b6..bbc7759fb012 100644 --- a/src/whiteboard/move.hpp +++ b/src/whiteboard/move.hpp @@ -35,7 +35,7 @@ class move : public action move(size_t team_index, bool hidden, unit& mover, const pathfind::marked_route& route, arrow_ptr arrow, fake_unit_ptr fake_unit); move(config const&, bool hidden); // For deserialization - virtual ~move(){} + virtual ~move(); virtual std::ostream& print(std::ostream& s) const; diff --git a/src/whiteboard/typedefs.hpp b/src/whiteboard/typedefs.hpp index a9d13f575512..90807912a1a1 100644 --- a/src/whiteboard/typedefs.hpp +++ b/src/whiteboard/typedefs.hpp @@ -40,6 +40,7 @@ static lg::log_domain log_whiteboard("whiteboard"); #include "game_display.hpp" class arrow; +class game_board; struct map_location; //not used in the typedefs, saves a few forward declarations class unit; class unit_map; //not used in the typedefs, saves a few forward declarations