Checkin of patch 1020 (file #4046: unit_map_final1.patch) for Sapient.
This commit is contained in:
parent
5507d8ff24
commit
deb8d64d16
3 changed files with 701 additions and 113 deletions
|
@ -604,25 +604,17 @@ void formula_ai::play_turn()
|
|||
move_formula_ = game_logic::formula::create_optional_formula(current_team().ai_parameters()["move"], &function_table);
|
||||
}
|
||||
//execute units formulas first
|
||||
std::vector<gamemap::location> formula_unit_loc;
|
||||
for(unit_map::const_iterator i = units_.begin(); i != units_.end(); ++i) {
|
||||
if( (i->second.side() == get_info().team_num) && i->second.has_formula() )
|
||||
|
||||
for(unit_map::unit_iterator i = units_.begin() ; i != units_.end() ; ++i)
|
||||
{
|
||||
if ( (i->second.side() == get_info().team_num) && i->second.has_formula() )
|
||||
{
|
||||
formula_unit_loc.push_back(i->first);
|
||||
}
|
||||
}
|
||||
|
||||
for(std::vector<gamemap::location>::const_iterator i = formula_unit_loc.begin() ; i != formula_unit_loc.end() ; ++i)
|
||||
{
|
||||
unit_map::const_iterator unit_it = units_.find(*i);
|
||||
if ( unit_it != units_.end() )
|
||||
{
|
||||
game_logic::const_formula_ptr formula(new game_logic::formula(unit_it->second.get_formula(), &function_table));
|
||||
game_logic::const_formula_ptr formula(new game_logic::formula(i->second.get_formula(), &function_table));
|
||||
game_logic::map_formula_callable callable(this);
|
||||
callable.add_ref();
|
||||
callable.add("me", variant(new unit_callable(*unit_it, current_team(), get_info().team_num)));
|
||||
callable.add("me", variant(new unit_callable(*i, current_team(), get_info().team_num)));
|
||||
make_move(formula, callable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
game_logic::map_formula_callable callable(this);
|
||||
|
|
428
src/unit_map.cpp
428
src/unit_map.cpp
|
@ -17,11 +17,17 @@
|
|||
|
||||
#include "unit.hpp"
|
||||
#include "unit_map.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#define WRN_NG LOG_STREAM(warn, engine)
|
||||
#define LOG_NG LOG_STREAM(info, engine)
|
||||
|
||||
typedef std::pair<std::string, std::pair<bool, std::pair<gamemap::location, unit>*> > umap_pair;
|
||||
|
||||
//! A unit map with a copy of a single unit in it.
|
||||
unit_map::unit_map(const gamemap::location &loc, const unit &u)
|
||||
unit_map::unit_map(const gamemap::location &loc, const unit &u) : num_iters_(0), num_invalid_(0)
|
||||
{
|
||||
add(new std::pair<gamemap::location,unit>(loc, u));
|
||||
}
|
||||
|
@ -34,8 +40,12 @@ unit_map::unit_map(const unit_map &that)
|
|||
unit_map &unit_map::operator =(const unit_map &that)
|
||||
{
|
||||
clear();
|
||||
for (pmap::const_iterator i = that.map_.begin(); i != that.map_.end(); i++) {
|
||||
add(new std::pair<gamemap::location,unit>(*i->second));
|
||||
num_iters_ = 0;
|
||||
num_invalid_ = 0;
|
||||
for (umap::const_iterator i = that.map_.begin(); i != that.map_.end(); i++) {
|
||||
if (i->second.first) {
|
||||
add(i->second.second);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -45,60 +55,422 @@ unit_map::~unit_map()
|
|||
delete_all();
|
||||
}
|
||||
|
||||
std::pair<gamemap::location,unit>* unit_map::unit_iterator::operator->() const
|
||||
{
|
||||
assert(valid());
|
||||
return i_->second.second;
|
||||
}
|
||||
|
||||
std::pair<gamemap::location,unit>& unit_map::unit_iterator::operator*() const
|
||||
{
|
||||
assert(valid());
|
||||
return *i_->second.second;
|
||||
}
|
||||
|
||||
unit_map::unit_iterator unit_map::unit_iterator::operator++() {
|
||||
|
||||
assert(i_ != map_->map_.end());
|
||||
|
||||
++i_;
|
||||
while (i_ != map_->map_.end() && !valid()) {
|
||||
++i_;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
unit_map::unit_iterator unit_map::unit_iterator::operator++(int){
|
||||
|
||||
assert(i_ != map_->map_.end());
|
||||
|
||||
umap::iterator iter(i_);
|
||||
++i_;
|
||||
while (i_ != map_->map_.end() && !valid()) {
|
||||
++i_;
|
||||
}
|
||||
|
||||
return unit_iterator(iter, map_);
|
||||
}
|
||||
|
||||
// Due to unit <-> unit_map dependencies, must be out of line.
|
||||
std::pair<gamemap::location,unit>& unit_map::iterator::operator*() const
|
||||
const std::pair<gamemap::location,unit>* unit_map::const_unit_iterator::operator->() const
|
||||
{
|
||||
return *i_->second;
|
||||
assert(valid());
|
||||
return i_->second.second;
|
||||
}
|
||||
const std::pair<gamemap::location,unit>& unit_map::const_iterator::operator*() const
|
||||
|
||||
const std::pair<gamemap::location,unit>& unit_map::const_unit_iterator::operator*() const
|
||||
{
|
||||
return *i_->second;
|
||||
assert(valid());
|
||||
return *i_->second.second;
|
||||
}
|
||||
|
||||
unit_map::const_unit_iterator unit_map::const_unit_iterator::operator++() {
|
||||
|
||||
assert(i_ != map_->map_.end());
|
||||
|
||||
++i_;
|
||||
while (i_ != map_->map_.end() && !valid()) {
|
||||
++i_;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
unit_map::const_unit_iterator unit_map::const_unit_iterator::operator--() {
|
||||
|
||||
umap::const_iterator begin = map_->begin().i_;
|
||||
|
||||
assert(i_ != begin);
|
||||
|
||||
--i_;
|
||||
while (i_ != begin && !valid()) {
|
||||
--i_;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
unit_map::const_unit_iterator unit_map::const_unit_iterator::operator++(int){
|
||||
|
||||
assert(i_ != map_->map_.end());
|
||||
|
||||
umap::const_iterator iter(i_);
|
||||
++i_;
|
||||
while (i_ != map_->map_.end() && !valid()) {
|
||||
++i_;
|
||||
}
|
||||
|
||||
return const_unit_iterator(iter, map_);
|
||||
}
|
||||
|
||||
unit_map::unit_xy_iterator::unit_xy_iterator(const unit_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) {
|
||||
if (i.valid()) loc_ = i->first;
|
||||
}
|
||||
|
||||
|
||||
std::pair<gamemap::location,unit>* unit_map::unit_xy_iterator::operator->() const
|
||||
{
|
||||
assert(valid());
|
||||
return i_->second.second;
|
||||
}
|
||||
|
||||
std::pair<gamemap::location,unit>& unit_map::unit_xy_iterator::operator*() const
|
||||
{
|
||||
assert(valid());
|
||||
return *i_->second.second;
|
||||
}
|
||||
|
||||
unit_map::unit_xy_iterator unit_map::unit_xy_iterator::operator++() {
|
||||
|
||||
assert(i_ != map_->map_.end());
|
||||
|
||||
++i_;
|
||||
while (i_ != map_->map_.end() && !valid()) {
|
||||
++i_;
|
||||
}
|
||||
|
||||
if (i_ != map_->map_.end()) {
|
||||
loc_ = i_->second.second->first;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
unit_map::unit_xy_iterator unit_map::unit_xy_iterator::operator++(int){
|
||||
|
||||
assert(i_ != map_->map_.end());
|
||||
|
||||
umap::iterator iter(i_);
|
||||
gamemap::location pre_loc = loc_;
|
||||
++i_;
|
||||
while (i_ != map_->map_.end() && !valid()) {
|
||||
++i_;
|
||||
}
|
||||
|
||||
if (i_ != map_->map_.end()) {
|
||||
loc_ = i_->second.second->first;
|
||||
}
|
||||
|
||||
return unit_xy_iterator(iter, map_, pre_loc);
|
||||
}
|
||||
|
||||
bool unit_map::unit_xy_iterator::valid() const {
|
||||
return i_ != map_->map_.end() && i_->second.first && loc_ == i_->second.second->first;
|
||||
}
|
||||
|
||||
unit_map::const_unit_xy_iterator::const_unit_xy_iterator(const unit_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) {
|
||||
if (i.valid()) loc_ = i->first;
|
||||
}
|
||||
|
||||
unit_map::const_unit_xy_iterator::const_unit_xy_iterator(const const_unit_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) {
|
||||
if (i.valid()) loc_ = i->first;
|
||||
}
|
||||
|
||||
const std::pair<gamemap::location,unit>* unit_map::const_unit_xy_iterator::operator->() const {
|
||||
assert(valid());
|
||||
return i_->second.second;
|
||||
}
|
||||
|
||||
const std::pair<gamemap::location,unit>& unit_map::const_unit_xy_iterator::operator*() const {
|
||||
assert(valid());
|
||||
return *i_->second.second;
|
||||
}
|
||||
|
||||
unit_map::const_unit_xy_iterator unit_map::const_unit_xy_iterator::operator++() {
|
||||
|
||||
assert(i_ != map_->map_.end());
|
||||
|
||||
++i_;
|
||||
while (i_ != map_->map_.end() && !valid()) {
|
||||
++i_;
|
||||
}
|
||||
|
||||
if (i_ != map_->map_.end()) {
|
||||
loc_ = i_->second.second->first;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
unit_map::const_unit_xy_iterator unit_map::const_unit_xy_iterator::operator++(int){
|
||||
|
||||
assert(i_ != map_->map_.end());
|
||||
|
||||
gamemap::location pre_loc = loc_;
|
||||
|
||||
umap::const_iterator iter(i_);
|
||||
++i_;
|
||||
while (i_ != map_->map_.end() && !valid()) {
|
||||
++i_;
|
||||
}
|
||||
|
||||
if (i_ != map_->map_.end()) {
|
||||
loc_ = i_->second.second->first;
|
||||
}
|
||||
|
||||
return const_unit_xy_iterator(iter, map_, pre_loc);
|
||||
}
|
||||
|
||||
bool unit_map::const_unit_xy_iterator::valid() const {
|
||||
return i_ != map_->map_.end() && i_->second.first && loc_ == i_->second.second->first;
|
||||
}
|
||||
|
||||
|
||||
unit_map::xy_accessor::xy_accessor(const unit_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) {
|
||||
if (i.valid()) loc_ = i->first;
|
||||
}
|
||||
|
||||
unit_map::xy_accessor::xy_accessor(const unit_xy_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) {
|
||||
if (i.valid()) loc_ = i->first;
|
||||
}
|
||||
|
||||
|
||||
std::pair<gamemap::location,unit>* unit_map::xy_accessor::operator->() {
|
||||
if (!valid()) { assert(0); }
|
||||
return i_->second.second;
|
||||
}
|
||||
|
||||
std::pair<gamemap::location,unit>& unit_map::xy_accessor::operator*() {
|
||||
if (!valid()) { assert(0); }
|
||||
return *i_->second.second;
|
||||
}
|
||||
|
||||
|
||||
bool unit_map::xy_accessor::valid() {
|
||||
if (i_->second.first && i_->second.second->first == loc_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
unit_iterator u_iter = map_->find(loc_);
|
||||
|
||||
if (u_iter.valid()) {
|
||||
i_ = u_iter.i_;
|
||||
loc_ = i_->second.second->first;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unit_map::const_xy_accessor::const_xy_accessor(const const_unit_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) {
|
||||
if (i.valid()) loc_ = i->first;
|
||||
}
|
||||
|
||||
unit_map::const_xy_accessor::const_xy_accessor(const unit_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) {
|
||||
if (i.valid()) loc_ = i->first;
|
||||
}
|
||||
|
||||
unit_map::const_xy_accessor::const_xy_accessor(const const_unit_xy_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) {
|
||||
if (i.valid()) loc_ = i->first;
|
||||
}
|
||||
|
||||
unit_map::const_xy_accessor::const_xy_accessor(const unit_xy_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) {
|
||||
if (i.valid()) loc_ = i->first;
|
||||
}
|
||||
|
||||
const std::pair<gamemap::location,unit>* unit_map::const_xy_accessor::operator->() {
|
||||
if (!valid()) { assert(0); }
|
||||
return i_->second.second;
|
||||
}
|
||||
|
||||
const std::pair<gamemap::location,unit>& unit_map::const_xy_accessor::operator*() {
|
||||
if (!valid()) { assert(0); }
|
||||
return *i_->second.second;
|
||||
}
|
||||
|
||||
|
||||
bool unit_map::const_xy_accessor::valid() {
|
||||
if (i_->second.first && i_->second.second->first == loc_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const_unit_iterator u_iter = map_->find(loc_);
|
||||
|
||||
if (u_iter.valid()) {
|
||||
i_ = u_iter.i_;
|
||||
loc_ = i_->second.second->first;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
unit_map::unit_iterator unit_map::find(const gamemap::location &loc) {
|
||||
lmap::const_iterator iter = lmap_.find(loc);
|
||||
if (iter == lmap_.end()) {
|
||||
return unit_iterator(map_.end(), this);
|
||||
}
|
||||
|
||||
umap::iterator i = map_.find(iter->second->second.underlying_id());
|
||||
i->second.second->first = loc;
|
||||
|
||||
return unit_iterator(i , this);
|
||||
}
|
||||
|
||||
|
||||
unit_map::const_unit_iterator unit_map::find(const gamemap::location &loc) const {
|
||||
lmap::const_iterator iter = lmap_.find(loc);
|
||||
if (iter == lmap_.end()) {
|
||||
return const_unit_iterator(map_.end(), this);
|
||||
}
|
||||
|
||||
umap::const_iterator i = map_.find(iter->second->second.underlying_id());
|
||||
i->second.second->first = loc;
|
||||
|
||||
return const_unit_iterator(i , this);
|
||||
}
|
||||
|
||||
unit_map::unit_iterator unit_map::begin() {
|
||||
// clean if there are more invalid than valid
|
||||
if (num_invalid_ > lmap_.size() && num_iters_ == 0) {
|
||||
clean_invalid();
|
||||
}
|
||||
|
||||
umap::iterator i = map_.begin();
|
||||
while (i != map_.end() && !i->second.first) {
|
||||
++i;
|
||||
}
|
||||
return unit_iterator(i, this);
|
||||
}
|
||||
|
||||
|
||||
void unit_map::add(std::pair<gamemap::location,unit> *p)
|
||||
{
|
||||
std::pair<pmap::iterator,bool> res = map_.insert(std::pair<gamemap::location,std::pair<gamemap::location,unit>*>(p->first, p));
|
||||
std::pair<lmap::iterator,bool> res = lmap_.insert(std::pair<gamemap::location,std::pair<gamemap::location,unit>*>(p->first, p));
|
||||
assert(res.second);
|
||||
|
||||
umap::iterator iter = map_.find(p->second.underlying_id());
|
||||
|
||||
if (iter != map_.end() && iter->second.first && iter->second.second->first != p->first) {
|
||||
WRN_NG << "unit_map::add -- duplicate unique id in unit_map: " << p->second.underlying_id() << "\n";
|
||||
}
|
||||
|
||||
if (iter != map_.end() && !iter->second.first) {
|
||||
num_invalid_--;
|
||||
}
|
||||
|
||||
map_[p->second.underlying_id()] = std::pair<bool, std::pair<gamemap::location, unit>*>(true, p);
|
||||
}
|
||||
|
||||
void unit_map::replace(std::pair<gamemap::location,unit> *p)
|
||||
{
|
||||
if (erase(p->first) != 1)
|
||||
assert(0);
|
||||
map_.insert(std::pair<gamemap::location,std::pair<gamemap::location,unit>*>(p->first, p));
|
||||
add(p);
|
||||
}
|
||||
|
||||
void unit_map::delete_all()
|
||||
{
|
||||
for (pmap::iterator i = map_.begin(); i != map_.end(); i++) {
|
||||
for (lmap::iterator i = lmap_.begin(); i != lmap_.end(); ++i) {
|
||||
delete(i->second);
|
||||
}
|
||||
|
||||
lmap_.clear();
|
||||
map_.clear();
|
||||
}
|
||||
|
||||
//! Extract (like erase, but don't delete).
|
||||
std::pair<gamemap::location,unit> *unit_map::extract(const gamemap::location &loc)
|
||||
{
|
||||
pmap::iterator i = map_.find(loc);
|
||||
if (i == map_.end())
|
||||
lmap::iterator i = lmap_.find(loc);
|
||||
if (i == lmap_.end())
|
||||
return NULL;
|
||||
std::pair<gamemap::location,unit> *res = i->second;
|
||||
map_.erase(i);
|
||||
std::pair<gamemap::location,unit> *res = i->second;
|
||||
|
||||
umap::iterator iter = map_.find(i->second->second.underlying_id());
|
||||
|
||||
lmap_.erase(i);
|
||||
|
||||
update_validity(iter);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t unit_map::erase(const gamemap::location &loc)
|
||||
{
|
||||
pmap::iterator i = map_.find(loc);
|
||||
if (i == map_.end())
|
||||
lmap::iterator i = lmap_.find(loc);
|
||||
if (i == lmap_.end())
|
||||
return 0;
|
||||
|
||||
|
||||
umap::iterator iter = map_.find(i->second->second.underlying_id());
|
||||
|
||||
delete i->second;
|
||||
map_.erase(i);
|
||||
lmap_.erase(i);
|
||||
|
||||
update_validity(iter);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void unit_map::erase(iterator pos)
|
||||
void unit_map::update_validity(umap::iterator iter)
|
||||
{
|
||||
lmap::const_iterator i;
|
||||
for (i = lmap_.begin(); i != lmap_.end(); ++i) {
|
||||
if (i->second->second.underlying_id() == iter->first) {
|
||||
iter->second.second = i->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == lmap_.end()) {
|
||||
if (iter->second.first) {
|
||||
iter->second.first = false;
|
||||
++num_invalid_;
|
||||
}
|
||||
} else {
|
||||
if (!iter->second.first) {
|
||||
iter->second.first = true;
|
||||
--num_invalid_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unit_map::erase(xy_accessor pos)
|
||||
{
|
||||
assert(pos.valid());
|
||||
|
||||
if (erase(pos->first) != 1)
|
||||
assert(0);
|
||||
}
|
||||
|
@ -106,5 +478,21 @@ void unit_map::erase(iterator pos)
|
|||
void unit_map::clear()
|
||||
{
|
||||
delete_all();
|
||||
map_.clear();
|
||||
}
|
||||
|
||||
void unit_map::clean_invalid() {
|
||||
size_t num_cleaned = 0;
|
||||
|
||||
umap::iterator iter;
|
||||
for (iter = map_.begin(); iter != map_.end(); ++iter) {
|
||||
if (!iter->second.first) {
|
||||
map_.erase(iter--);
|
||||
num_cleaned++;
|
||||
}
|
||||
}
|
||||
|
||||
num_invalid_ -= num_cleaned;
|
||||
|
||||
LOG_NG << "unit_map::clean_invalid - removed " << num_cleaned << " invalid map entries.\n";
|
||||
}
|
||||
|
||||
|
|
364
src/unit_map.hpp
364
src/unit_map.hpp
|
@ -34,103 +34,296 @@ class unit;
|
|||
|
||||
class unit_map
|
||||
{
|
||||
private:
|
||||
|
||||
//! Used so unit_map can keep a count of iterators and clean invalid pointers when no iterators exist. Every iterator and accessor has a counter instance.
|
||||
struct iterator_counter {
|
||||
iterator_counter() : has_map_(false) {}
|
||||
iterator_counter(const unit_map* map) : map_(map), has_map_(true)
|
||||
{ map_->add_iter(); }
|
||||
|
||||
iterator_counter(const iterator_counter& i) : has_map_(i.has_map_) {
|
||||
if (has_map_)
|
||||
{ map_ = i.map_; map_->add_iter(); }
|
||||
}
|
||||
|
||||
iterator_counter &operator =(const iterator_counter &that) {
|
||||
if (this == &that)
|
||||
return *this;
|
||||
|
||||
if (has_map_) map_->remove_iter();
|
||||
|
||||
has_map_ = that.has_map_;
|
||||
|
||||
if (has_map_) {
|
||||
map_=that.map_;
|
||||
map_->add_iter();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~iterator_counter() {if (has_map_) map_->remove_iter(); }
|
||||
private:
|
||||
const unit_map* map_;
|
||||
bool has_map_;
|
||||
};
|
||||
|
||||
public:
|
||||
unit_map() { };
|
||||
unit_map() : num_iters_(0), num_invalid_(0) { };
|
||||
unit_map(const unit_map &that);
|
||||
unit_map &operator =(const unit_map &that);
|
||||
//! A unit map with a single unit in it.
|
||||
explicit unit_map(const gamemap::location &loc, const unit &u);
|
||||
~unit_map();
|
||||
|
||||
//! Keyed with unit's underlying_id. bool flag is whether the following pair pointer is valid. pointer to pair used to imitate a map<location, unit>
|
||||
typedef std::map<std::string,std::pair<bool, std::pair<gamemap::location,unit>*> > umap;
|
||||
|
||||
//! Maintains only the valid pairs. Used to determine validity in umap, and for faster lookup by location.
|
||||
typedef std::map<gamemap::location, std::pair<gamemap::location, unit>*> lmap;
|
||||
|
||||
struct const_unit_iterator;
|
||||
struct unit_xy_iterator;
|
||||
struct const_unit_xy_iterator;
|
||||
struct xy_accessor;
|
||||
struct const_xy_accessor;
|
||||
|
||||
//! We actually keep map to pointers to pairs. Easy to fake iterators.
|
||||
typedef std::map<gamemap::location,std::pair<gamemap::location,unit>*> pmap;
|
||||
struct iterator;
|
||||
struct const_iterator {
|
||||
const_iterator() { }
|
||||
const_iterator(const iterator &i) : i_(i.i_) { }
|
||||
|
||||
const std::pair<gamemap::location,unit>* operator->() const
|
||||
{ return i_->second; }
|
||||
|
||||
const std::pair<gamemap::location,unit>& operator*() const;
|
||||
|
||||
const_iterator operator++()
|
||||
{ return const_iterator(++i_); }
|
||||
|
||||
const_iterator operator++(int)
|
||||
{ return const_iterator(i_++); }
|
||||
|
||||
const_iterator operator--()
|
||||
{ return const_iterator(--i_); }
|
||||
|
||||
bool operator==(const const_iterator &that) const
|
||||
{ return that.i_ == this->i_; }
|
||||
|
||||
bool operator!=(const const_iterator &that) const
|
||||
{ return that.i_ != this->i_; }
|
||||
|
||||
explicit const_iterator(pmap::const_iterator i) : i_(i) { }
|
||||
|
||||
private:
|
||||
pmap::const_iterator i_;
|
||||
};
|
||||
|
||||
struct iterator {
|
||||
iterator() { }
|
||||
|
||||
std::pair<gamemap::location,unit> *operator->() const
|
||||
{ return i_->second; }
|
||||
|
||||
//! For iterating over every unit. Iterator is valid as long as there is there is a unit w/ matching underlying_id in the map.
|
||||
struct unit_iterator
|
||||
{
|
||||
unit_iterator() { }
|
||||
|
||||
unit_iterator(const unit_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) { }
|
||||
unit_iterator(umap::iterator i, unit_map* map) : counter(map), i_(i), map_(map) { }
|
||||
|
||||
std::pair<gamemap::location,unit> *operator->() const;
|
||||
std::pair<gamemap::location,unit>& operator*() const;
|
||||
|
||||
iterator operator++()
|
||||
{ return iterator(++i_); }
|
||||
unit_iterator operator++();
|
||||
unit_iterator operator++(int);
|
||||
|
||||
|
||||
iterator operator++(int)
|
||||
{ return iterator(i_++); }
|
||||
|
||||
bool operator==(const iterator &that) const
|
||||
bool operator==(const unit_iterator &that) const
|
||||
{ return that.i_ == this->i_; }
|
||||
|
||||
bool operator!=(const iterator &that) const
|
||||
bool operator!=(const unit_iterator &that) const
|
||||
{ return that.i_ != this->i_; }
|
||||
|
||||
explicit iterator(pmap::iterator i) : i_(i) { }
|
||||
|
||||
friend struct const_iterator;
|
||||
|
||||
bool valid() const
|
||||
{ return i_ != map_->map_.end() && i_->second.first; }
|
||||
|
||||
friend struct const_unit_iterator;
|
||||
friend struct unit_xy_iterator;
|
||||
friend struct const_unit_xy_iterator;
|
||||
friend struct xy_accessor;
|
||||
friend struct const_xy_accessor;
|
||||
|
||||
private:
|
||||
pmap::iterator i_;
|
||||
iterator_counter counter;
|
||||
|
||||
umap::iterator i_;
|
||||
unit_map* map_;
|
||||
};
|
||||
|
||||
struct const_unit_iterator
|
||||
{
|
||||
const_unit_iterator(const unit_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) { }
|
||||
|
||||
const_unit_iterator() { }
|
||||
|
||||
const_unit_iterator(const const_unit_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_) { }
|
||||
const_unit_iterator(umap::const_iterator i, const unit_map* map): counter(map), i_(i), map_(map) { }
|
||||
|
||||
const std::pair<gamemap::location,unit>* operator->() const;
|
||||
const std::pair<gamemap::location,unit>& operator*() const;
|
||||
|
||||
iterator find(const gamemap::location &loc) {
|
||||
return iterator(map_.find(loc));
|
||||
}
|
||||
const_iterator find(const gamemap::location &loc) const {
|
||||
return const_iterator(map_.find(loc));
|
||||
}
|
||||
const_unit_iterator operator++();
|
||||
|
||||
const_unit_iterator operator++(int);
|
||||
|
||||
const_unit_iterator operator--();
|
||||
|
||||
bool operator==(const const_unit_iterator &that) const
|
||||
{ return that.i_ == this->i_; }
|
||||
|
||||
bool operator!=(const const_unit_iterator &that) const
|
||||
{ return that.i_ != this->i_; }
|
||||
|
||||
bool valid() const
|
||||
{ return i_ != map_->map_.end() && i_->second.first; }
|
||||
|
||||
friend struct const_unit_xy_iterator;
|
||||
friend struct const_xy_accessor;
|
||||
|
||||
private:
|
||||
iterator_counter counter;
|
||||
|
||||
umap::const_iterator i_;
|
||||
const unit_map* map_;
|
||||
};
|
||||
|
||||
typedef unit_iterator iterator;
|
||||
typedef const_unit_iterator const_iterator;
|
||||
|
||||
//! Similar to unit_iterator, except that becomes invalid if unit is moved while the iterator points at it. Can update to the new position w/ update_loc().
|
||||
struct unit_xy_iterator
|
||||
{
|
||||
unit_xy_iterator(const unit_iterator &i);
|
||||
|
||||
unit_xy_iterator() { }
|
||||
|
||||
unit_xy_iterator(const unit_xy_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_)
|
||||
{ if (i.valid()) loc_ = i.loc_; }
|
||||
|
||||
unit_xy_iterator(umap::iterator i, unit_map* map, gamemap::location loc): counter(map), i_(i), map_(map), loc_(loc) { }
|
||||
|
||||
std::pair<gamemap::location,unit>* operator->() const;
|
||||
std::pair<gamemap::location,unit>& operator*() const;
|
||||
|
||||
unit_xy_iterator operator++();
|
||||
|
||||
unit_xy_iterator operator++(int);
|
||||
|
||||
bool operator==(const unit_xy_iterator &that) const
|
||||
{ return that.i_ == this->i_; }
|
||||
|
||||
bool operator!=(const unit_xy_iterator &that) const
|
||||
{ return that.i_ != this->i_; }
|
||||
|
||||
bool valid() const;
|
||||
|
||||
friend struct const_unit_xy_iterator;
|
||||
friend struct xy_accessor;
|
||||
friend struct const_xy_accessor;
|
||||
|
||||
private:
|
||||
iterator_counter counter;
|
||||
|
||||
umap::iterator i_;
|
||||
unit_map* map_;
|
||||
|
||||
gamemap::location loc_;
|
||||
};
|
||||
|
||||
struct const_unit_xy_iterator
|
||||
{
|
||||
const_unit_xy_iterator(const unit_iterator &i);
|
||||
const_unit_xy_iterator(const const_unit_iterator &i);
|
||||
|
||||
const_unit_xy_iterator() { }
|
||||
|
||||
const_unit_xy_iterator(umap::const_iterator i, const unit_map* map, gamemap::location loc): counter(map), i_(i), map_(map), loc_(loc) { }
|
||||
|
||||
const_unit_xy_iterator(const unit_xy_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_)
|
||||
{ if (i.valid()) loc_ = i.loc_; }
|
||||
const_unit_xy_iterator(const const_unit_xy_iterator &i) : counter(i.map_), i_(i.i_), map_(i.map_)
|
||||
{ if (i.valid()) loc_ = i.loc_; }
|
||||
|
||||
const std::pair<gamemap::location,unit>* operator->() const;
|
||||
const std::pair<gamemap::location,unit>& operator*() const;
|
||||
|
||||
const_unit_xy_iterator operator++();
|
||||
|
||||
const_unit_xy_iterator operator++(int);
|
||||
|
||||
bool operator==(const const_unit_xy_iterator &that) const
|
||||
{ return that.i_ == this->i_; }
|
||||
|
||||
bool operator!=(const const_unit_xy_iterator &that) const
|
||||
{ return that.i_ != this->i_; }
|
||||
|
||||
bool valid() const;
|
||||
|
||||
friend struct const_xy_accessor;
|
||||
|
||||
private:
|
||||
iterator_counter counter;
|
||||
|
||||
umap::const_iterator i_;
|
||||
const unit_map* map_;
|
||||
|
||||
gamemap::location loc_;
|
||||
};
|
||||
|
||||
//! Used to access the unit at a given position. Is valid as long as any unit is in that position. Can switch from invalid to valid.
|
||||
struct xy_accessor
|
||||
{
|
||||
xy_accessor(const unit_iterator &i);
|
||||
xy_accessor(const unit_xy_iterator &i);
|
||||
xy_accessor() { }
|
||||
|
||||
std::pair<gamemap::location,unit>* operator->();
|
||||
std::pair<gamemap::location,unit>& operator*();
|
||||
|
||||
bool valid();
|
||||
|
||||
private:
|
||||
iterator_counter counter;
|
||||
|
||||
umap::iterator i_;
|
||||
unit_map* map_;
|
||||
|
||||
gamemap::location loc_;
|
||||
};
|
||||
|
||||
struct const_xy_accessor
|
||||
{
|
||||
const_xy_accessor(const unit_iterator &i);
|
||||
const_xy_accessor(const unit_xy_iterator &i);
|
||||
const_xy_accessor(const const_unit_iterator &i);
|
||||
const_xy_accessor(const const_unit_xy_iterator &i);
|
||||
|
||||
const_xy_accessor() { }
|
||||
|
||||
const std::pair<gamemap::location,unit>* operator->();
|
||||
const std::pair<gamemap::location,unit>& operator*();
|
||||
|
||||
bool valid();
|
||||
|
||||
private:
|
||||
iterator_counter counter;
|
||||
|
||||
umap::const_iterator i_;
|
||||
const unit_map* map_;
|
||||
|
||||
gamemap::location loc_;
|
||||
};
|
||||
|
||||
//! Return object can be implicitly converted to any of the other iterators or accessors
|
||||
unit_iterator find(const gamemap::location &loc) ;
|
||||
|
||||
//! Return object can be implicity converted to any of the other const iterators or accessors
|
||||
const_unit_iterator find(const gamemap::location &loc) const;
|
||||
|
||||
size_t count(const gamemap::location &loc) const {
|
||||
return map_.count(loc);
|
||||
return lmap_.count(loc);
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return iterator(map_.begin());
|
||||
//! Return object can be implicitly converted to any of the other iterators or accessors
|
||||
unit_iterator begin();
|
||||
|
||||
//! Return object can be implicity converted to any of the other const iterators or accessors
|
||||
const_unit_iterator begin() const {
|
||||
umap::const_iterator i = map_.begin();
|
||||
while (i != map_.end() && !i->second.first) {
|
||||
++i;
|
||||
}
|
||||
return const_unit_iterator(i, this);
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(map_.begin());
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(map_.end());
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(map_.end());
|
||||
//! Return object can be implicitly converted to any of the other iterators or accessors
|
||||
unit_iterator end() {
|
||||
return iterator(map_.end(), this);
|
||||
}
|
||||
|
||||
//! Return object can be implicity converted to any of the other const iterators or accessors
|
||||
const_unit_iterator end() const {
|
||||
return const_iterator(map_.end(), this);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return map_.size();
|
||||
return lmap_.size();
|
||||
}
|
||||
|
||||
void clear();
|
||||
|
@ -138,25 +331,40 @@ public:
|
|||
//! Extract (like erase, only don't delete).
|
||||
std::pair<gamemap::location,unit> *extract(const gamemap::location &loc);
|
||||
|
||||
//! Map owns pointer after this. Loc must be currently empty.
|
||||
//! Map owns pointer after this. Loc must be currently empty. unit's underlying_id should not be present in the map already
|
||||
void add(std::pair<gamemap::location,unit> *p);
|
||||
|
||||
//! Like add, but loc must be occupied (implicitly erased).
|
||||
void replace(std::pair<gamemap::location,unit> *p);
|
||||
|
||||
void erase(iterator pos);
|
||||
void erase(xy_accessor pos);
|
||||
size_t erase(const gamemap::location &loc);
|
||||
|
||||
void swap(unit_map& o) {
|
||||
map_.swap(o.map_);
|
||||
lmap_.swap(o.lmap_);
|
||||
}
|
||||
|
||||
|
||||
//! Removes invalid entries in map_. Called automatically when safe and needed.
|
||||
void clean_invalid();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void update_validity(umap::iterator iter);
|
||||
void delete_all();
|
||||
|
||||
void add_iter() const { ++num_iters_; }
|
||||
void remove_iter() const { --num_iters_; }
|
||||
|
||||
//! A map of pairs is redundant, but makes it possible to imitate a map of location,unit.
|
||||
std::map<gamemap::location,std::pair<gamemap::location,unit>*> map_;
|
||||
|
||||
//! Key: unit's underlying_id. bool indicates validity of pointer. pointer to pair used to imitate a map<location, unit>
|
||||
std::map<std::string,std::pair<bool, std::pair<gamemap::location,unit>*> > map_;
|
||||
|
||||
//! Maintains only the valid pairs. Used to determine validity in umap, and for faster lookup by location.
|
||||
std::map<gamemap::location, std::pair<gamemap::location, unit>*> lmap_;
|
||||
|
||||
mutable size_t num_iters_;
|
||||
size_t num_invalid_;
|
||||
};
|
||||
|
||||
#endif // UNIT_MAP_H_INCLUDED
|
||||
|
|
Loading…
Add table
Reference in a new issue