change fake_unit class to fake_unit_ptr

This is consistent with the introduction of the UnitPtr class.
fake_units really aren't different from units, the only difference
is their life time / allocation and ownership. Since we are trying
to use reference counting for all units (to make them safe to use
with animations), the fake units need to be managed by a reference
counted pointer also. This is the easiest way to achieve that.

I also remove some odd code the [move_units_fake] handler --
there was explicit code to remove the fake units from the fake
unit manager, but this is redundant as it is the responsibility
of the destructor.

Code Blocks and VC project files are updated, but
Code::Blocks Scons and Xcode are not.
This commit is contained in:
Chris Beck 2014-06-18 20:26:01 -04:00
parent e803a9d12d
commit 0f5876fe38
23 changed files with 212 additions and 144 deletions

View file

@ -296,10 +296,10 @@
<Unit filename="..\..\src\events.cpp" />
<Unit filename="..\..\src\events.hpp" />
<Unit filename="..\..\src\exceptions.hpp" />
<Unit filename="..\..\src\fake_unit.cpp" />
<Unit filename="..\..\src\fake_unit.hpp" />
<Unit filename="..\..\src\fake_unit_manager.cpp" />
<Unit filename="..\..\src\fake_unit_manager.hpp" />
<Unit filename="..\..\src\fake_unit_ptr.cpp" />
<Unit filename="..\..\src\fake_unit_ptr.hpp" />
<Unit filename="..\..\src\filechooser.cpp" />
<Unit filename="..\..\src\filechooser.hpp" />
<Unit filename="..\..\src\filesystem.cpp" />

View file

@ -20136,14 +20136,6 @@
RelativePath="..\..\src\exceptions.hpp"
>
</File>
<File
RelativePath="..\..\src\fake_unit.cpp"
>
</File>
<File
RelativePath="..\..\src\fake_unit.hpp"
>
</File>
<File
RelativePath="..\..\src\fake_unit_manager.cpp"
>
@ -20152,6 +20144,14 @@
RelativePath="..\..\src\fake_unit_manager.hpp"
>
</File>
<File
RelativePath="..\..\src\fake_unit_ptr.cpp"
>
</File>
<File
RelativePath="..\..\src\fake_unit_ptr.hpp"
>
</File>
<File
RelativePath="..\..\src\filechooser.cpp"
>

View file

@ -729,8 +729,8 @@ set(wesnoth-main_SRC
editor/editor_preferences.cpp
editor/toolkit/editor_toolkit.cpp
editor/map/context_manager.cpp
fake_unit.cpp
fake_unit_manager.cpp
fake_unit_ptr.cpp
filechooser.cpp
flg_manager.cpp
floating_textbox.cpp

View file

@ -262,8 +262,8 @@ wesnoth_sources = Split("""
editor/editor_preferences.cpp
editor/toolkit/brush.cpp
editor/toolkit/editor_toolkit.cpp
fake_unit.cpp
fake_unit_manager.cpp
fake_unit_ptr.cpp
filechooser.cpp
flg_manager.cpp
floating_textbox.cpp

View file

@ -513,7 +513,7 @@ namespace { // Private helpers for move_unit()
// Show this move.
const size_t current_tracking = game_events::wml_tracking();
animator.proceed_to(*move_it_, step_to - begin_,
animator.proceed_to(move_it_.get_shared_ptr(), step_to - begin_,
current_tracking != do_move_track_, false);
do_move_track_ = current_tracking;
disp.redraw_minimap();
@ -942,7 +942,7 @@ namespace { // Private helpers for move_unit()
// Prepare to animate.
unit_display::unit_mover animator(route_, show);
animator.start(*move_it_);
animator.start(move_it_.get_shared_ptr());
// Traverse the route to the hex where we need to stop.
// Each iteration performs the move from real_end_-1 to real_end_.
@ -1003,7 +1003,7 @@ namespace { // Private helpers for move_unit()
if ( move_it_.valid() ) {
// Finish animating.
animator.finish(*move_it_);
animator.finish(move_it_.get_shared_ptr());
// Check for the moving unit being seen.
event_mutated_ = actor_sighted(*move_it_, &not_seeing);
}

View file

@ -740,7 +740,7 @@ bool undo_list::move_action::undo(int side, undo_list & /*undos*/)
goto_hex = u->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();

View file

@ -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<unit*>::iterator it =
std::deque<internal_ptr_type>::iterator it =
std::remove(fake_units_.begin(), fake_units_.end(), u);
if (it != fake_units_.end()) {
removed = std::distance(it, fake_units_.end());

View file

@ -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<std::deque<unit*>::const_iterator> range;
typedef unit const * internal_ptr_type;
typedef boost::iterator_range<std::deque<internal_ptr_type>::const_iterator> range;
range get_unit_range() const { return boost::make_iterator_range(fake_units_.begin(), fake_units_.end()); }

View file

@ -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 <boost/swap.hpp>
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;

View file

@ -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<unit const &>(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

View file

@ -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"

View file

@ -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<unit> 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<map_location>& 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<util::unique_ptr<fake_unit> > units(
new util::unique_ptr<fake_unit>[num_units]);
std::vector<fake_unit_ptr > units;
units.reserve(num_units);
std::vector<std::vector<map_location> > paths;
paths.reserve(num_units);
@ -1364,8 +1364,8 @@ WML_HANDLER_FUNCTION(move_units_fake, /*event_info*/, cfg)
const std::vector<std::string> xvals = utils::split(config["x"]);
const std::vector<std::string> 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();

View file

@ -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);
}

View file

@ -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;
}
}
/**

View file

@ -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<map_location>& 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<map_location>& path, unit& u,
void move_unit(const std::vector<map_location>& path, UnitPtr u,
bool animate, map_location::DIRECTION dir,
bool force_scroll)
{

View file

@ -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 @@ public:
explicit unit_mover(const std::vector<map_location>& 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 @@ private: // data
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<map_location>& 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 @@ private: // data
/**
* Display a unit moving along a given path.
*/
void move_unit(const std::vector<map_location>& path, unit& u,
void move_unit(const std::vector<map_location>& path, UnitPtr u,
bool animate=true,
map_location::DIRECTION dir=map_location::NDIRECTIONS,
bool force_scroll=false);

View file

@ -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"

View file

@ -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"

View file

@ -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);

View file

@ -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();

View file

@ -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()

View file

@ -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();
}

View file

@ -37,11 +37,11 @@ static lg::log_domain log_whiteboard("whiteboard");
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#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<bool> whiteboard_lock;
typedef boost::shared_ptr<arrow> arrow_ptr;
typedef boost::shared_ptr<fake_unit> fake_unit_ptr;
typedef boost::shared_ptr<action> action_ptr;
typedef boost::shared_ptr<action const> action_const_ptr;