Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add fake_unit_manager, split off from game_display object
This commit adds two classes -- fake_unit, and fake_unit_manager, both split off from code contained in game_display. The display object is reconfigured to hold a pointer to the manager and display the units it contains. The rest of the code is configured to add fake units to the manager, not the display. This improves encapsulation and helps to reduce the game_display class.
- Loading branch information
Showing
31 changed files
with
332 additions
and
208 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
Copyright (C) 2014 by Chris Beck <render787@gmail.com> | ||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/ | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation; either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY. | ||
See the COPYING file for more details. | ||
*/ | ||
|
||
#include "fake_unit.hpp" | ||
|
||
#include "fake_unit_manager.hpp" | ||
|
||
/** | ||
* Assignment operator, taking a unit. | ||
* If already in the queue, @a this will be moved to the end of the | ||
* queue (drawn last). | ||
* | ||
* This function is unsuitable for derived classes and MUST be overridden. | ||
* Furthermore, derived classes must not explicitly call this version. | ||
* | ||
* 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) | ||
{ | ||
if ( this != &a ) { | ||
fake_unit_manager * mgr = my_manager_; | ||
|
||
// Use the copy constructor to make sure we are coherent. | ||
// (Methodology copied from unit::operator=) | ||
this->~fake_unit(); | ||
new (this) fake_unit(a); | ||
// Restore our old manager. | ||
if ( mgr != NULL ) | ||
place_on_fake_unit_manager(mgr); | ||
} | ||
return *this; | ||
} | ||
|
||
/** | ||
* Removes @a this from the fake_units_ list if necessary. | ||
*/ | ||
fake_unit::~fake_unit() | ||
{ | ||
try { | ||
// The fake_unit class exists for this one line, which removes the | ||
// fake_unit from the managers's fake_units_ dequeue in the event of an | ||
// exception. | ||
if(my_manager_){remove_from_fake_unit_manager();} | ||
|
||
} catch (...) {} | ||
} | ||
|
||
/** | ||
* Place @a this on @a manager's fake_units_ dequeue. | ||
* 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){ | ||
assert(my_manager_ == NULL); //Can only be placed on 1 fake_unit_manager | ||
my_manager_=manager; | ||
my_manager_->place_temporary_unit(this); | ||
} | ||
|
||
/** | ||
* Removes @a this from whatever fake_units_ list it is on (if any). | ||
* @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 ret(0); | ||
if(my_manager_ != NULL){ | ||
ret = my_manager_->remove_temporary_unit(this); | ||
my_manager_=NULL; | ||
} | ||
return ret; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
Copyright (C) 2014 by Chris Beck <render787@gmail.com> | ||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/ | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation; either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY. | ||
See the COPYING file for more details. | ||
*/ | ||
|
||
#ifndef INCL_FAKE_UNIT_HPP_ | ||
#define INCL_FAKE_UNIT_HPP_ | ||
|
||
#include "unit.hpp" | ||
|
||
class fake_unit_manager; | ||
|
||
/** A temporary unit that can be placed on the map. | ||
Temporary units can overlap units. | ||
Adding the same unit twice isn't allowed. | ||
The fake_unit owns its underlying unit and when | ||
it goes out of scope it removes itself from the fake_units list. | ||
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 { | ||
public: | ||
explicit fake_unit(unit const & u) : unit(u), my_manager_(NULL) {} | ||
fake_unit(fake_unit const & u) : unit(u), my_manager_(NULL) {} | ||
fake_unit(const unit_type& t, int side, unit_race::GENDER gender = unit_race::NUM_GENDERS) | ||
: unit(t, side, false, gender) | ||
, my_manager_(NULL) | ||
{} | ||
/// 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); | ||
/// Removes @a this from the fake_units_ list if necessary. | ||
~fake_unit(); | ||
|
||
/// 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 : | ||
fake_unit_manager * my_manager_; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
Copyright (C) 2014 by Chris Beck <render787@gmail.com> | ||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/ | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation; either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY. | ||
See the COPYING file for more details. | ||
*/ | ||
|
||
#include "fake_unit_manager.hpp" | ||
|
||
#include "display.hpp" | ||
#include "fake_unit.hpp" | ||
#include "log.hpp" | ||
#include "unit.hpp" | ||
|
||
static lg::log_domain log_engine("engine"); | ||
#define ERR_NG LOG_STREAM(err, log_engine) | ||
|
||
void fake_unit_manager::place_temporary_unit(unit *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; | ||
} else { | ||
fake_units_.push_back(u); | ||
my_display_.invalidate(u->get_location()); | ||
} | ||
} | ||
|
||
int fake_unit_manager::remove_temporary_unit(unit *u) | ||
{ | ||
int removed = 0; | ||
std::deque<unit*>::iterator it = | ||
std::remove(fake_units_.begin(), fake_units_.end(), u); | ||
if (it != fake_units_.end()) { | ||
removed = std::distance(it, fake_units_.end()); | ||
//std::remove doesn't remove anything without using erase afterwards. | ||
fake_units_.erase(it, fake_units_.end()); | ||
my_display_.invalidate(u->get_location()); | ||
// Redraw with no location to get rid of haloes | ||
u->clear_haloes(); | ||
} | ||
if (removed > 1) { | ||
ERR_NG << "Error: duplicate temp unit found in fake_unit_manager::remove_temporary_unit" << std::endl; | ||
} | ||
return removed; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
Copyright (C) 2014 by Chris Beck <render787@gmail.com> | ||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/ | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation; either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY. | ||
See the COPYING file for more details. | ||
*/ | ||
|
||
#ifndef INCL_FAKE_UNIT_MGR_HPP_ | ||
#define INCL_FAKE_UNIT_MGR_HPP_ | ||
|
||
#include <deque> | ||
|
||
class display; | ||
class unit; | ||
class fake_unit; | ||
|
||
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; | ||
|
||
const std::deque<unit*> & get_fake_unit_list_for_invalidation() {return fake_units_; } | ||
|
||
private: | ||
/** Temporarily place a unit on map (moving: can overlap others). | ||
* The temp unit is added at the end of the temporary unit dequeue, | ||
* and therefore gets drawn last, over other units and temp units. | ||
* Adding the same unit twice isn't allowed. | ||
*/ | ||
void place_temporary_unit(unit *u); | ||
|
||
/** Removes any instances of this temporary unit from the temporary unit vector. | ||
* Returns the number of temp units deleted (0 or 1, any other number indicates an error). | ||
*/ | ||
int remove_temporary_unit(unit *u); | ||
|
||
/// collection of units destined to be drawn but not put into the unit map | ||
std::deque<unit*> fake_units_; | ||
display & my_display_; | ||
}; | ||
|
||
#endif |
Oops, something went wrong.