diff --git a/projectfiles/CodeBlocks/wesnoth.cbp b/projectfiles/CodeBlocks/wesnoth.cbp index 50d11e593580..44b6e44fea8a 100644 --- a/projectfiles/CodeBlocks/wesnoth.cbp +++ b/projectfiles/CodeBlocks/wesnoth.cbp @@ -296,10 +296,10 @@ - - + + diff --git a/projectfiles/VC9/wesnoth.vcproj b/projectfiles/VC9/wesnoth.vcproj index 7fbc2b132e59..153050349f2b 100644 --- a/projectfiles/VC9/wesnoth.vcproj +++ b/projectfiles/VC9/wesnoth.vcproj @@ -20137,19 +20137,19 @@ > get_goto(); // Move the unit. - unit_display::move_unit(rev_route, *u, true, starting_dir); + unit_display::move_unit(rev_route, u.get_shared_ptr(), true, starting_dir); units.move(u->get_location(), rev_route.back()); unit::clear_status_caches(); @@ -957,7 +957,7 @@ bool undo_list::move_action::redo(int side) starting_moves = u->movement_left(); // Move the unit. - unit_display::move_unit(route, *u); + unit_display::move_unit(route, u.get_shared_ptr()); units.move(u->get_location(), route.back()); u = units.find(route.back()); unit::clear_status_caches(); diff --git a/src/fake_unit_manager.cpp b/src/fake_unit_manager.cpp index cafae7b726d8..313dfb5dcff3 100644 --- a/src/fake_unit_manager.cpp +++ b/src/fake_unit_manager.cpp @@ -15,7 +15,7 @@ #include "fake_unit_manager.hpp" #include "display.hpp" -#include "fake_unit.hpp" +#include "fake_unit_ptr.hpp" #include "log.hpp" #include "unit.hpp" #include "unit_animation_component.hpp" @@ -23,7 +23,7 @@ static lg::log_domain log_engine("engine"); #define ERR_NG LOG_STREAM(err, log_engine) -void fake_unit_manager::place_temporary_unit(unit *u) +void fake_unit_manager::place_temporary_unit(internal_ptr_type u) { if(std::find(fake_units_.begin(),fake_units_.end(), u) != fake_units_.end()) { ERR_NG << "In fake_unit_manager::place_temporary_unit: attempt to add duplicate fake unit." << std::endl; @@ -33,10 +33,10 @@ void fake_unit_manager::place_temporary_unit(unit *u) } } -int fake_unit_manager::remove_temporary_unit(unit *u) +int fake_unit_manager::remove_temporary_unit(internal_ptr_type u) { int removed = 0; - std::deque::iterator it = + std::deque::iterator it = std::remove(fake_units_.begin(), fake_units_.end(), u); if (it != fake_units_.end()) { removed = std::distance(it, fake_units_.end()); diff --git a/src/fake_unit_manager.hpp b/src/fake_unit_manager.hpp index eee3f17e31b4..78ec1083aa99 100644 --- a/src/fake_unit_manager.hpp +++ b/src/fake_unit_manager.hpp @@ -21,17 +21,17 @@ class display; class unit; -class fake_unit; +class fake_unit_ptr; class fake_unit_manager { public: fake_unit_manager(display & disp) : fake_units_(), my_display_(disp) {} //Anticipate making place_temporary_unit and remove_temporary_unit private to force exception safety - friend class fake_unit; + friend class fake_unit_ptr; - typedef unit* internal_ptr_type; - typedef boost::iterator_range::const_iterator> range; + typedef unit const * internal_ptr_type; + typedef boost::iterator_range::const_iterator> range; range get_unit_range() const { return boost::make_iterator_range(fake_units_.begin(), fake_units_.end()); } diff --git a/src/fake_unit.cpp b/src/fake_unit_ptr.cpp similarity index 61% rename from src/fake_unit.cpp rename to src/fake_unit_ptr.cpp index 3fbb09442a1c..5a37a83f3c21 100644 --- a/src/fake_unit.cpp +++ b/src/fake_unit_ptr.cpp @@ -12,9 +12,33 @@ See the COPYING file for more details. */ -#include "fake_unit.hpp" +#include "fake_unit_ptr.hpp" #include "fake_unit_manager.hpp" +#include "unit.hpp" +#include "unit_ptr.hpp" +#include "unit_types.hpp" + +#include + +fake_unit_ptr::fake_unit_ptr() : unit_(), my_manager_(NULL) {} +fake_unit_ptr::fake_unit_ptr(const internal_ptr & u) : unit_(u), my_manager_(NULL) {} +fake_unit_ptr::fake_unit_ptr(const internal_ptr & u, fake_unit_manager * mgr) : unit_(u), my_manager_(NULL) +{ + place_on_fake_unit_manager(mgr); +} +fake_unit_ptr::fake_unit_ptr(const fake_unit_ptr & ptr) : unit_(ptr.unit_), my_manager_(NULL) {} + +void fake_unit_ptr::swap (fake_unit_ptr & o) { + boost::swap(unit_, o.unit_); + std::swap(my_manager_, o.my_manager_); +} + +fake_unit_ptr & fake_unit_ptr::operator=(fake_unit_ptr other) { + swap(other); + return *this; +} + /** * Assignment operator, taking a unit. @@ -27,7 +51,7 @@ * The overriding function can be almost the same, except "new (this)" should * be followed by the derived class instead of "fake_unit(a)". */ -fake_unit & fake_unit::operator=(unit const & a) +/*fake_unit & fake_unit::operator=(unit const & a) { if ( this != &a ) { fake_unit_manager * mgr = my_manager_; @@ -41,12 +65,30 @@ fake_unit & fake_unit::operator=(unit const & a) place_on_fake_unit_manager(mgr); } return *this; +}*/ + +void fake_unit_ptr::reset() +{ + remove_from_fake_unit_manager(); + unit_.reset(); +} + +void fake_unit_ptr::reset(const internal_ptr & ptr) +{ + if (unit_.get() != ptr.get()) { + fake_unit_manager * mgr = my_manager_; + + remove_from_fake_unit_manager(); + unit_ = ptr; + if (mgr) + place_on_fake_unit_manager(mgr); + } } /** * Removes @a this from the fake_units_ list if necessary. */ -fake_unit::~fake_unit() +fake_unit_ptr::~fake_unit_ptr() { try { // The fake_unit class exists for this one line, which removes the @@ -62,10 +104,10 @@ fake_unit::~fake_unit() * This will be added at the end (drawn last, over all other units). * Duplicate additions are not allowed. */ -void fake_unit::place_on_fake_unit_manager(fake_unit_manager * manager){ +void fake_unit_ptr::place_on_fake_unit_manager(fake_unit_manager * manager){ assert(my_manager_ == NULL); //Can only be placed on 1 fake_unit_manager my_manager_=manager; - my_manager_->place_temporary_unit(this); + my_manager_->place_temporary_unit(unit_.get()); } /** @@ -73,10 +115,10 @@ void fake_unit::place_on_fake_unit_manager(fake_unit_manager * manager){ * @returns the number of fake_units deleted, which should be 0 or 1 * (any other number indicates an error). */ -int fake_unit::remove_from_fake_unit_manager(){ +int fake_unit_ptr::remove_from_fake_unit_manager(){ int ret(0); if(my_manager_ != NULL){ - ret = my_manager_->remove_temporary_unit(this); + ret = my_manager_->remove_temporary_unit(unit_.get()); my_manager_=NULL; } return ret; diff --git a/src/fake_unit.hpp b/src/fake_unit_ptr.hpp similarity index 50% rename from src/fake_unit.hpp rename to src/fake_unit_ptr.hpp index bf1c3f65b4ab..699a84e14877 100644 --- a/src/fake_unit.hpp +++ b/src/fake_unit_ptr.hpp @@ -15,7 +15,8 @@ #ifndef INCL_FAKE_UNIT_HPP_ #define INCL_FAKE_UNIT_HPP_ -#include "unit.hpp" +#include "unit_ptr.hpp" +#include "unit_types.hpp" class fake_unit_manager; @@ -27,31 +28,62 @@ class fake_unit_manager; The intent is to provide exception safety when the code creating the temp unit is unexpectedly forced out of scope. */ -class fake_unit : public unit { +class fake_unit_ptr { public: - explicit fake_unit(unit const & u) : unit(u), my_manager_(NULL) {ref_count_ = ref_count_ + 1; } //prevent UnitPtr from deleting this - fake_unit(fake_unit const & u) : unit(u), my_manager_(NULL) {ref_count_ = ref_count_ + 1; } - fake_unit(const unit_type& t, int side, unit_race::GENDER gender = unit_race::NUM_GENDERS) - : unit(t, side, false, gender) - , my_manager_(NULL) - {ref_count_ = ref_count_ + 1; } - /// Assignment operator, taking a fake_unit. - /// If already in the queue, @a this will be moved to the end of the - /// queue (drawn last). The queue (if any) of the parameter is ignored. - fake_unit & operator=(fake_unit const & u) - { return operator=(static_cast(u)); } - /// Assignment operator, taking a unit. - virtual fake_unit & operator=(unit const & u); + typedef UnitPtr internal_ptr; + typedef UnitConstPtr internal_const_ptr; + + fake_unit_ptr(); + explicit fake_unit_ptr(const internal_ptr & u); + fake_unit_ptr(const internal_ptr & u, fake_unit_manager * mgr); + fake_unit_ptr(const fake_unit_ptr & ptr); + + void swap (fake_unit_ptr & o); + + fake_unit_ptr & operator=(fake_unit_ptr other); + + void reset(); + void reset(const internal_ptr & ptr); + + internal_ptr operator->() { return unit_; } + internal_const_ptr operator->() const { return unit_; } + + internal_ptr get_unit_ptr() { return unit_; } + internal_const_ptr get_unit_ptr() const { return unit_; } + + unit & operator*() { return *unit_; } + unit * get() { return unit_.get(); } + /// Removes @a this from the fake_units_ list if necessary. - ~fake_unit(); + ~fake_unit_ptr(); /// Place @a this on @a manager's fake_units_ dequeue. void place_on_fake_unit_manager(fake_unit_manager * d); /// Removes @a this from whatever fake_units_ list it is on (if any). int remove_from_fake_unit_manager(); - private : +private : + internal_ptr unit_; fake_unit_manager * my_manager_; + +#ifndef HAVE_CXX11 + struct safe_bool_impl { void nonnull() {} }; + /** + * Used as t he return type of the conversion operator for boolean contexts. + * Needed, since the compiler would otherwise consider the following + * conversion (C legacy): cfg["abc"] -> "abc"[bool(cfg)] -> 'b' + */ + typedef void (safe_bool_impl::*safe_bool)(); +#endif + +public: +#ifdef HAVE_CXX11 + explicit operator bool() const + { return unit_; } +#else + operator safe_bool() const + { return unit_ ? &safe_bool_impl::nonnull : NULL; } +#endif }; #endif diff --git a/src/game_display.cpp b/src/game_display.cpp index 0b835baf40e1..b96ea697bdd9 100644 --- a/src/game_display.cpp +++ b/src/game_display.cpp @@ -35,8 +35,8 @@ Growl_Delegate growl_obj; #include "cursor.hpp" #include "drawable_unit.hpp" -#include "fake_unit.hpp" #include "fake_unit_manager.hpp" +#include "fake_unit_ptr.hpp" #include "game_board.hpp" #include "game_preferences.hpp" #include "halo.hpp" @@ -48,6 +48,7 @@ Growl_Delegate growl_obj; #include "resources.hpp" #include "tod_manager.hpp" #include "sound.hpp" +#include "unit.hpp" #include "whiteboard/manager.hpp" #ifdef _WIN32 #include "windows_tray_notification.hpp" diff --git a/src/game_events/action_wml.cpp b/src/game_events/action_wml.cpp index 102324455c01..0f462523d8b9 100644 --- a/src/game_events/action_wml.cpp +++ b/src/game_events/action_wml.cpp @@ -30,8 +30,8 @@ #include "../actions/vision.hpp" #include "../ai/manager.hpp" #include "../dialogs.hpp" -#include "../fake_unit.hpp" #include "../fake_unit_manager.hpp" +#include "../fake_unit_ptr.hpp" #include "../game_classification.hpp" #include "../game_display.hpp" #include "../game_preferences.hpp" @@ -226,7 +226,7 @@ namespace { // Support functions return map_location(x, y); } - fake_unit *create_fake_unit(const vconfig& cfg) + fake_unit_ptr create_fake_unit(const vconfig& cfg) { std::string type = cfg["type"]; std::string variation = cfg["variation"]; @@ -238,8 +238,8 @@ namespace { // Support functions unit_race::GENDER gender = string_gender(cfg["gender"]); const unit_type *ut = unit_types.find(type); - if (!ut) return NULL; - fake_unit * fake = new fake_unit(*ut, side_num, gender); + if (!ut) return fake_unit_ptr(); + fake_unit_ptr fake = fake_unit_ptr(UnitPtr(new unit(*ut, side_num, gender))); if(!variation.empty()) { config mod; @@ -1326,7 +1326,7 @@ WML_HANDLER_FUNCTION(modify_turns, /*event_info*/, cfg) /// that is just moving for the visual effect WML_HANDLER_FUNCTION(move_unit_fake, /*event_info*/, cfg) { - util::unique_ptr dummy_unit(create_fake_unit(cfg)); + fake_unit_ptr dummy_unit(create_fake_unit(cfg)); if(!dummy_unit.get()) return; @@ -1341,7 +1341,7 @@ WML_HANDLER_FUNCTION(move_unit_fake, /*event_info*/, cfg) const std::vector& path = fake_unit_path(*dummy_unit, xvals, yvals); if (!path.empty()) { // Always scroll. - unit_display::move_unit(path, *dummy_unit, true, map_location::NDIRECTIONS, force_scroll); + unit_display::move_unit(path, dummy_unit.get_unit_ptr(), true, map_location::NDIRECTIONS, force_scroll); } } @@ -1351,8 +1351,8 @@ WML_HANDLER_FUNCTION(move_units_fake, /*event_info*/, cfg) const vconfig::child_list unit_cfgs = cfg.get_children("fake_unit"); size_t num_units = unit_cfgs.size(); - boost::scoped_array > units( - new util::unique_ptr[num_units]); + std::vector units; + units.reserve(num_units); std::vector > paths; paths.reserve(num_units); @@ -1364,8 +1364,8 @@ WML_HANDLER_FUNCTION(move_units_fake, /*event_info*/, cfg) const std::vector xvals = utils::split(config["x"]); const std::vector yvals = utils::split(config["y"]); int skip_steps = config["skip_steps"]; - fake_unit *u = create_fake_unit(config); - units[paths.size()].reset(u); + fake_unit_ptr u = create_fake_unit(config); + units[paths.size()] = u; paths.push_back(fake_unit_path(*u, xvals, yvals)); if(skip_steps > 0) paths.back().insert(paths.back().begin(), skip_steps, paths.back().front()); @@ -1373,7 +1373,7 @@ WML_HANDLER_FUNCTION(move_units_fake, /*event_info*/, cfg) DBG_NG << "Path " << paths.size() - 1 << " has length " << paths.back().size() << '\n'; u->set_location(paths.back().front()); - u->place_on_fake_unit_manager(resources::fake_units); + u.place_on_fake_unit_manager(resources::fake_units); } LOG_NG << "Units placed, longest path is " << longest_path << " long\n"; @@ -1388,19 +1388,13 @@ WML_HANDLER_FUNCTION(move_units_fake, /*event_info*/, cfg) DBG_NG << "Moving unit " << un << ", doing step " << step << '\n'; path_step[0] = paths[un][step - 1]; path_step[1] = paths[un][step]; - unit_display::move_unit(path_step, *units[un]); + unit_display::move_unit(path_step, units[un].get_unit_ptr()); units[un]->set_location(path_step[1]); units[un]->anim_comp().set_standing(); } } LOG_NG << "Units moved\n"; - - for(size_t un = 0; un < num_units; ++un) { - units[un]->remove_from_fake_unit_manager(); - } - - LOG_NG << "Units removed\n"; } WML_HANDLER_FUNCTION(object, event_info, cfg) @@ -2321,7 +2315,7 @@ WML_HANDLER_FUNCTION(teleport, event_info, cfg) teleport_path.push_back(src_loc); teleport_path.push_back(vacant_dst); bool animate = cfg["animate"].to_bool(); - unit_display::move_unit(teleport_path, *u, animate); + unit_display::move_unit(teleport_path, u.get_shared_ptr(), animate); resources::units->move(src_loc, vacant_dst); unit::clear_status_caches(); diff --git a/src/mouse_events.cpp b/src/mouse_events.cpp index 93f96be210f0..e46d5e73da0f 100644 --- a/src/mouse_events.cpp +++ b/src/mouse_events.cpp @@ -215,7 +215,7 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update, m gui().clear_attack_indicator(); } - unit* un; //will later point to unit at mouseover_hex_ + UnitPtr un; //will later point to unit at mouseover_hex_ // the destination is the pointed hex or the adjacent hex // used to attack it @@ -271,9 +271,9 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update, m unit_map::iterator iter = mouseover_unit; if (iter != board_.units_.end()) - un = &*iter; + un = iter.get_shared_ptr(); else - un = NULL; + un.reset(); } //end planned unit map scope if ( (!selected_hex_.valid()) && un && current_paths_.destinations.empty() && @@ -286,7 +286,7 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update, m pathfind::marked_route route; { // start planned unit map scope wb::future_map_if_active raii; - route = get_route(un, go_to, current_team()); + route = get_route(un.get(), go_to, current_team()); } // end planned unit map scope gui().set_route(&route); } diff --git a/src/unit.cpp b/src/unit.cpp index 06ea00fe6056..31aa94824ad6 100644 --- a/src/unit.cpp +++ b/src/unit.cpp @@ -86,6 +86,10 @@ void intrusive_ptr_add_ref(const unit * u) // or if you are sure that the refcounting system works // then feel free to remove the next line assert(u->ref_count_ < 100000); + LOG_UT << "Adding a reference to a unit: id = " << u->id() << ", uid = " << u->underlying_id() << ", refcount = " << u->ref_count() << " ptr:" << u << std::endl; + if (u->ref_count_ == 0) { + LOG_UT << "Freshly constructed" << std::endl; + } ++(u->ref_count_); } @@ -93,8 +97,12 @@ void intrusive_ptr_release(const unit * u) { assert(u->ref_count_ >= 1); assert(u->ref_count_ < 100000); //See comment in intrusive_ptr_add_ref + LOG_UT << "Removing a reference to a unit: id = " << u->id() << ", uid = " << u->underlying_id() << ", refcount = " << u->ref_count() << " ptr:" << u << std::endl; if (--(u->ref_count_) == 0) + { + LOG_UT << "Deleting a unit: id = " << u->id() << ", uid = " << u->underlying_id() << std::endl; delete u; + } } /** diff --git a/src/unit_display.cpp b/src/unit_display.cpp index 3ccbe3c4c7a3..83946efb455a 100644 --- a/src/unit_display.cpp +++ b/src/unit_display.cpp @@ -17,8 +17,8 @@ #include "global.hpp" #include "unit_display.hpp" -#include "fake_unit.hpp" #include "fake_unit_manager.hpp" +#include "fake_unit_ptr.hpp" #include "game_board.hpp" #include "game_display.hpp" #include "game_preferences.hpp" @@ -116,7 +116,7 @@ static void teleport_unit_between(const map_location& a, const map_location& b, * INT_MIN indicates that no animation is pending. */ static int move_unit_between(const map_location& a, const map_location& b, - unit& temp_unit, unsigned int step_num, + UnitPtr temp_unit, unsigned int step_num, unsigned int step_left, unit_animator & animator, display& disp) { @@ -124,10 +124,10 @@ static int move_unit_between(const map_location& a, const map_location& b, return INT_MIN; } - temp_unit.set_location(a); + temp_unit->set_location(a); disp.invalidate(a); - temp_unit.set_facing(a.get_relative_dir(b)); - animator.replace_anim_if_invalid(&temp_unit,"movement",a,b,step_num, + temp_unit->set_facing(a.get_relative_dir(b)); + animator.replace_anim_if_invalid(temp_unit.get(),"movement",a,b,step_num, false,"",0,unit_animation::INVALID,NULL,NULL,step_left); animator.start_animations(); animator.pause_animation(); @@ -165,10 +165,10 @@ unit_mover::unit_mover(const std::vector& path, bool animate, bool force_scroll_(force_scroll), animator_(), wait_until_(INT_MIN), - shown_unit_(NULL), + shown_unit_(), path_(path), current_(0), - temp_unit_ptr_(NULL), + temp_unit_ptr_(), // Somewhat arbitrary default values. was_hidden_(false), is_enemy_(true) @@ -187,8 +187,6 @@ unit_mover::~unit_mover() update_shown_unit(); // For safety, clear the animator before deleting the temp unit. animator_.clear(); - // The temp unit's destructor will remove it from the display. - delete temp_unit_ptr_; } @@ -202,28 +200,24 @@ unit_mover::~unit_mover() /* Note: Hide the unit in its current location; do not actually remove it. * Otherwise the status displays will be wrong during the movement. */ -void unit_mover::replace_temporary(unit & u) +void unit_mover::replace_temporary(UnitPtr u) { if ( disp_ == NULL ) // No point in creating a temp unit with no way to display it. return; // Save the hidden state of the unit. - was_hidden_ = u.get_hidden(); + was_hidden_ = u->get_hidden(); // Make our temporary unit mostly match u... - if ( temp_unit_ptr_ == NULL ) { - temp_unit_ptr_ = new fake_unit(u); - temp_unit_ptr_->place_on_fake_unit_manager(resources::fake_units); - } - else - *temp_unit_ptr_ = u; + temp_unit_ptr_ = fake_unit_ptr(UnitPtr(new unit(*u)), resources::fake_units); + // ... but keep the temporary unhidden and hide the original. temp_unit_ptr_->set_hidden(false); - u.set_hidden(true); + u->set_hidden(true); // Update cached data. - is_enemy_ = (*resources::teams)[u.side()-1].is_enemy(disp_->viewing_side()); + is_enemy_ = (*resources::teams)[u->side()-1].is_enemy(disp_->viewing_side()); } @@ -234,11 +228,11 @@ void unit_mover::replace_temporary(unit & u) */ void unit_mover::update_shown_unit() { - if ( shown_unit_ != NULL ) { + if ( shown_unit_ ) { // Switch the display back to the real unit. shown_unit_->set_hidden(was_hidden_); temp_unit_ptr_->set_hidden(true); - shown_unit_ = NULL; + shown_unit_.reset(); } } @@ -247,15 +241,15 @@ void unit_mover::update_shown_unit() * Initiates the display of movement for the supplied unit. * This should be called before attempting to display moving to a new hex. */ -void unit_mover::start(unit& u) +void unit_mover::start(UnitPtr u) { // Nothing to do here if there is nothing to animate. if ( !can_draw_ ) return; // If no animation then hide unit until end of movement if ( !animate_ ) { - was_hidden_ = u.get_hidden(); - u.set_hidden(true); + was_hidden_ = u->get_hidden(); + u->set_hidden(true); return; } @@ -294,15 +288,15 @@ void unit_mover::start(unit& u) disp_->draw(true); // extra immobile movement animation for take-off - animator_.add_animation(temp_unit_ptr_, "pre_movement", path_[0], path_[1]); + animator_.add_animation(temp_unit_ptr_.get(), "pre_movement", path_[0], path_[1]); animator_.start_animations(); animator_.wait_for_end(); animator_.clear(); // Switch the display back to the real unit. - u.set_facing(temp_unit_ptr_->facing()); - u.anim_comp().set_standing(false); // Need to reset u's animation so the new facing takes effect. - u.set_hidden(was_hidden_); + u->set_facing(temp_unit_ptr_->facing()); + u->anim_comp().set_standing(false); // Need to reset u's animation so the new facing takes effect. + u->set_hidden(was_hidden_); temp_unit_ptr_->set_hidden(true); } @@ -318,7 +312,7 @@ void unit_mover::start(unit& u) * wait (another call to proceed_to() or finish() will implicitly wait). The * unit must remain valid until the wait is finished. */ -void unit_mover::proceed_to(unit& u, size_t path_index, bool update, bool wait) +void unit_mover::proceed_to(UnitPtr u, size_t path_index, bool update, bool wait) { // Nothing to do here if animations cannot be shown. if ( !can_draw_ || !animate_ ) @@ -327,14 +321,14 @@ void unit_mover::proceed_to(unit& u, size_t path_index, bool update, bool wait) // Handle pending visibility issues before introducing new ones. wait_for_anims(); - if ( update || temp_unit_ptr_ == NULL ) + if ( update || !temp_unit_ptr_ ) // Replace the temp unit (which also hides u and shows our temporary). replace_temporary(u); else { // Just switch the display from the real unit to our fake one. temp_unit_ptr_->set_hidden(false); - u.set_hidden(true); + u->set_hidden(true); } // Safety check. @@ -367,7 +361,7 @@ void unit_mover::proceed_to(unit& u, size_t path_index, bool update, bool wait) if ( tiles_adjacent(path_[current_], path_[current_+1]) ) wait_until_ = move_unit_between(path_[current_], path_[current_+1], - *temp_unit_ptr_, current_, + temp_unit_ptr_.get_unit_ptr(), current_, path_.size() - (current_+2), animator_, *disp_); else if ( path_[current_] != path_[current_+1] ) @@ -376,10 +370,10 @@ void unit_mover::proceed_to(unit& u, size_t path_index, bool update, bool wait) } // Update the unit's facing. - u.set_facing(temp_unit_ptr_->facing()); - u.anim_comp().set_standing(false); // Need to reset u's animation so the new facing takes effect. + u->set_facing(temp_unit_ptr_->facing()); + u->anim_comp().set_standing(false); // Need to reset u's animation so the new facing takes effect. // Remember the unit to unhide when the animation finishes. - shown_unit_ = &u; + shown_unit_ = u; if ( wait ) wait_for_anims(); } @@ -417,7 +411,7 @@ void unit_mover::wait_for_anims() * If @a dir is not supplied, the final direction will be determined by (the * last two traversed hexes of) the path. */ -void unit_mover::finish(unit &u, map_location::DIRECTION dir) +void unit_mover::finish(UnitPtr u, map_location::DIRECTION dir) { // Nothing to do here if the display is not valid. if ( !can_draw_ ) @@ -438,13 +432,13 @@ void unit_mover::finish(unit &u, map_location::DIRECTION dir) temp_unit_ptr_->set_facing(final_dir); // Animation - animator_.add_animation(temp_unit_ptr_, "post_movement", end_loc); + animator_.add_animation(temp_unit_ptr_.get(), "post_movement", end_loc); animator_.start_animations(); animator_.wait_for_end(); animator_.clear(); // Switch the display back to the real unit. - u.set_hidden(was_hidden_); + u->set_hidden(was_hidden_); temp_unit_ptr_->set_hidden(true); events::mouse_handler* mousehandler = events::mouse_handler::get_singleton(); @@ -455,12 +449,12 @@ void unit_mover::finish(unit &u, map_location::DIRECTION dir) else { // Show the unit at end of skipped animation - u.set_hidden(was_hidden_); + u->set_hidden(was_hidden_); } // Facing gets set even when not animating. - u.set_facing(dir == map_location::NDIRECTIONS ? final_dir : dir); - u.anim_comp().set_standing(true); // Need to reset u's animation so the new facing takes effect. + u->set_facing(dir == map_location::NDIRECTIONS ? final_dir : dir); + u->anim_comp().set_standing(true); // Need to reset u's animation so the new facing takes effect. // Redraw path ends (even if not animating). disp_->invalidate(path_.front()); @@ -484,7 +478,7 @@ void unit_mover::finish(unit &u, map_location::DIRECTION dir) * so that while the unit is moving status etc. * will still display the correct number of units. */ -void move_unit(const std::vector& path, unit& u, +void move_unit(const std::vector& path, UnitPtr u, bool animate, map_location::DIRECTION dir, bool force_scroll) { diff --git a/src/unit_display.hpp b/src/unit_display.hpp index 15d45fa14d38..c39a2584d5bc 100644 --- a/src/unit_display.hpp +++ b/src/unit_display.hpp @@ -20,11 +20,11 @@ #ifndef UNIT_DISPLAY_HPP_INCLUDED #define UNIT_DISPLAY_HPP_INCLUDED +#include "fake_unit_ptr.hpp" #include "map_location.hpp" #include "unit_animation.hpp" class attack_type; -class fake_unit; class fake_unit_manager; class game_board; class game_display; @@ -49,13 +49,13 @@ class unit_mover : public boost::noncopyable { explicit unit_mover(const std::vector& path, bool animate=true, bool force_scroll=false); ~unit_mover(); - void start(unit& u); - void proceed_to(unit& u, size_t path_index, bool update=false, bool wait=true); + void start(UnitPtr u); + void proceed_to(UnitPtr u, size_t path_index, bool update=false, bool wait=true); void wait_for_anims(); - void finish(unit &u, map_location::DIRECTION dir = map_location::NDIRECTIONS); + void finish(UnitPtr u, map_location::DIRECTION dir = map_location::NDIRECTIONS); private: // functions - void replace_temporary(unit & u); + void replace_temporary(UnitPtr u); void update_shown_unit(); private: // data @@ -65,10 +65,10 @@ class unit_mover : public boost::noncopyable { const bool force_scroll_; unit_animator animator_; int wait_until_; /// The animation potential to wait until. INT_MIN for no wait; INT_MAX to wait for end. - unit * shown_unit_; /// The unit to be (re-)shown after an animation finishes. + UnitPtr shown_unit_; /// The unit to be (re-)shown after an animation finishes. const std::vector& path_; size_t current_; - fake_unit * temp_unit_ptr_; + fake_unit_ptr temp_unit_ptr_; bool was_hidden_; bool is_enemy_; }; @@ -77,7 +77,7 @@ class unit_mover : public boost::noncopyable { /** * Display a unit moving along a given path. */ -void move_unit(const std::vector& path, unit& u, +void move_unit(const std::vector& path, UnitPtr u, bool animate=true, map_location::DIRECTION dir=map_location::NDIRECTIONS, bool force_scroll=false); diff --git a/src/whiteboard/attack.cpp b/src/whiteboard/attack.cpp index dff4cc065c60..d1c88c72b5c7 100644 --- a/src/whiteboard/attack.cpp +++ b/src/whiteboard/attack.cpp @@ -23,7 +23,7 @@ #include "arrow.hpp" #include "config.hpp" -#include "fake_unit.hpp" +#include "fake_unit_ptr.hpp" #include "game_board.hpp" #include "play_controller.hpp" #include "resources.hpp" diff --git a/src/whiteboard/highlighter.cpp b/src/whiteboard/highlighter.cpp index 18516117e156..7084ddf664ea 100644 --- a/src/whiteboard/highlighter.cpp +++ b/src/whiteboard/highlighter.cpp @@ -35,7 +35,7 @@ #include "arrow.hpp" #include "config.hpp" -#include "fake_unit.hpp" +#include "fake_unit_ptr.hpp" #include "game_board.hpp" #include "game_display.hpp" #include "game_errors.hpp" diff --git a/src/whiteboard/manager.cpp b/src/whiteboard/manager.cpp index ba2c00284391..34de296da111 100644 --- a/src/whiteboard/manager.cpp +++ b/src/whiteboard/manager.cpp @@ -32,8 +32,8 @@ #include "actions/undo.hpp" #include "arrow.hpp" #include "chat_events.hpp" -#include "fake_unit.hpp" #include "fake_unit_manager.hpp" +#include "fake_unit_ptr.hpp" #include "formula_string_utils.hpp" #include "game_board.hpp" #include "game_preferences.hpp" @@ -714,12 +714,11 @@ void manager::create_temp_move() if(!fake_unit) { // Create temp ghost unit - fake_unit.reset(new class fake_unit(*temp_moved_unit)); - fake_unit->place_on_fake_unit_manager( resources::fake_units); + fake_unit = fake_unit_ptr(UnitPtr (new unit(*temp_moved_unit)), resources::fake_units); fake_unit->anim_comp().set_ghosted(true); } - unit_display::move_unit(path, *fake_unit, false); //get facing right + unit_display::move_unit(path, fake_unit.get_unit_ptr(), false); //get facing right fake_unit->anim_comp().invalidate(*game_display::get_singleton()); fake_unit->set_location(*curr_itor); fake_unit->anim_comp().set_ghosted(true); diff --git a/src/whiteboard/move.cpp b/src/whiteboard/move.cpp index e6ded93e559a..ca4ca92e5df9 100644 --- a/src/whiteboard/move.cpp +++ b/src/whiteboard/move.cpp @@ -25,8 +25,8 @@ #include "arrow.hpp" #include "config.hpp" -#include "fake_unit.hpp" #include "fake_unit_manager.hpp" +#include "fake_unit_ptr.hpp" #include "game_board.hpp" #include "game_end_exceptions.hpp" #include "mouse_events.hpp" @@ -132,12 +132,11 @@ move::move(config const& cfg, bool hidden) arrow_->set_path(route_->steps); // Construct fake_unit_ - fake_unit_.reset(new fake_unit(*get_unit()) ); + fake_unit_ = fake_unit_ptr( UnitPtr(new unit(*get_unit())) , resources::fake_units ); if(hidden) fake_unit_->set_hidden(true); - fake_unit_->place_on_fake_unit_manager(resources::fake_units); fake_unit_->anim_comp().set_ghosted(true); - unit_display::move_unit(route_->steps, *fake_unit_, false); //get facing right + unit_display::move_unit(route_->steps, fake_unit_.get_unit_ptr(), false); //get facing right fake_unit_->set_location(route_->steps.back()); this->init(); diff --git a/src/whiteboard/recall.cpp b/src/whiteboard/recall.cpp index d0d7ae2ab8e1..f055c2b30245 100644 --- a/src/whiteboard/recall.cpp +++ b/src/whiteboard/recall.cpp @@ -24,8 +24,8 @@ #include "visitor.hpp" #include "actions/create.hpp" -#include "fake_unit.hpp" #include "fake_unit_manager.hpp" +#include "fake_unit_ptr.hpp" #include "game_display.hpp" #include "recall_list_manager.hpp" #include "resources.hpp" @@ -62,7 +62,7 @@ recall::recall(size_t team_index, bool hidden, const unit& unit, const map_locat action(team_index,hidden), temp_unit_(new class unit(unit)), recall_hex_(recall_hex), - fake_unit_(new fake_unit(unit) ) + fake_unit_(UnitPtr( new class unit(unit) ) ) { this->init(); } @@ -79,7 +79,7 @@ recall::recall(config const& cfg, bool hidden) { if(recall_unit->underlying_id()==underlying_id) { - temp_unit_.reset(new unit(*recall_unit)); //TODO: is it necessary to make a copy? + temp_unit_.reset(new class unit(*recall_unit)); //TODO: is it necessary to make a copy? break; } } @@ -87,7 +87,7 @@ recall::recall(config const& cfg, bool hidden) throw action::ctor_err("recall: Invalid underlying_id"); } - fake_unit_.reset(new fake_unit(*temp_unit_)); //makes copy of temp_unit_ + fake_unit_.reset(UnitPtr(new class unit(*temp_unit_))); //makes copy of temp_unit_ this->init(); } @@ -101,7 +101,7 @@ void recall::init() fake_unit_->set_movement(0, true); fake_unit_->set_attacks(0); fake_unit_->anim_comp().set_ghosted(false); - fake_unit_->place_on_fake_unit_manager( resources::fake_units); + fake_unit_.place_on_fake_unit_manager( resources::fake_units); } recall::~recall() diff --git a/src/whiteboard/recruit.cpp b/src/whiteboard/recruit.cpp index 2c1feaa6ec8c..339a214d6b4a 100644 --- a/src/whiteboard/recruit.cpp +++ b/src/whiteboard/recruit.cpp @@ -23,8 +23,8 @@ #include "utility.hpp" #include "visitor.hpp" -#include "fake_unit.hpp" #include "fake_unit_manager.hpp" +#include "fake_unit_ptr.hpp" #include "menu_events.hpp" #include "play_controller.hpp" #include "resources.hpp" @@ -58,7 +58,7 @@ recruit::recruit(size_t team_index, bool hidden, const std::string& unit_name, c unit_name_(unit_name), recruit_hex_(recruit_hex), temp_unit_(create_corresponding_unit()), //auto-ptr ownership transfer - fake_unit_(new fake_unit(*temp_unit_)), //temp_unit_ *copied* into new fake unit + fake_unit_(UnitPtr(new unit(*temp_unit_))), //temp_unit_ *copied* into new fake unit cost_(0) { this->init(); @@ -78,7 +78,7 @@ recruit::recruit(config const& cfg, bool hidden) // Construct temp_unit_ and fake_unit_ temp_unit_ = create_corresponding_unit(); //auto-ptr ownership transfer - fake_unit_.reset(new class fake_unit(*temp_unit_)), //temp_unit_ copied into new fake_unit + fake_unit_.reset(UnitPtr (new unit(*temp_unit_))), //temp_unit_ copied into new fake_unit this->init(); } @@ -89,7 +89,7 @@ void recruit::init() fake_unit_->set_movement(0, true); fake_unit_->set_attacks(0); fake_unit_->anim_comp().set_ghosted(false); - fake_unit_->place_on_fake_unit_manager(resources::fake_units); + fake_unit_.place_on_fake_unit_manager(resources::fake_units); cost_ = fake_unit_->type().cost(); } diff --git a/src/whiteboard/typedefs.hpp b/src/whiteboard/typedefs.hpp index 7626166289d8..6535e37f1bdb 100644 --- a/src/whiteboard/typedefs.hpp +++ b/src/whiteboard/typedefs.hpp @@ -37,11 +37,11 @@ static lg::log_domain log_whiteboard("whiteboard"); #include #include +#include "../fake_unit_ptr.hpp" #include "../unit_ptr.hpp" class arrow; class config; -class fake_unit; class fake_unit_manager; class game_board; struct map_location; //not used in the typedefs, saves a few forward declarations @@ -66,7 +66,6 @@ class side_actions; typedef boost::shared_ptr whiteboard_lock; typedef boost::shared_ptr arrow_ptr; -typedef boost::shared_ptr fake_unit_ptr; typedef boost::shared_ptr action_ptr; typedef boost::shared_ptr action_const_ptr;