25 #define ERR_NG LOG_STREAM(err, log_engine)
26 #define WRN_NG LOG_STREAM(warn, log_engine)
27 #define LOG_NG LOG_STREAM(info, log_engine)
28 #define DBG_NG LOG_STREAM(debug, log_engine)
40 for(
const auto& u : that) {
41 add(u.get_location(), u);
70 while(
i !=
umap_.end() && (!
i->second.unit)) {
86 if(res.second ==
false) {
96 DBG_NG <<
"Unit map: Moving unit from " << src <<
" to " << dst;
116 p->set_location(dst);
120 std::pair<lmap::iterator, bool> res =
lmap_.emplace(dst, uit);
123 if(res.second ==
false) {
124 p->set_location(src);
125 lmap_.emplace(src, uit);
143 std::size_t unit_id =
p->underlying_id();
147 ERR_NG <<
"Trying to add " <<
p->name() <<
" - " <<
p->id() <<
" at an invalid location; Discarding.";
154 DBG_NG <<
"Adding unit " <<
p->underlying_id() <<
" - " <<
p->id() <<
" to location: (" << loc <<
")";
156 std::pair<umap::iterator, bool> uinsert =
umap_.emplace(unit_id, upod);
158 if(!uinsert.second) {
160 if(!uinsert.first->second.unit) {
161 unit_pod& opod = uinsert.first->second;
166 unit_ptr q = uinsert.first->second.unit;
167 ERR_NG <<
"Trying to add " <<
p->name()
168 <<
" - " <<
p->id() <<
" - " <<
p->underlying_id()
169 <<
" (" << loc <<
") over " << q->name()
170 <<
" - " << q->id() <<
" - " << q->underlying_id()
171 <<
" (" << q->get_location()
174 p->mark_clone(
false);
175 ERR_NG <<
"The new unit was assigned underlying_id=" <<
p->underlying_id()
176 <<
" to prevent duplicate id conflicts.";
178 uinsert =
umap_.emplace(
p->underlying_id(), upod);
181 while(!uinsert.second && (++guard < 1e6)) {
182 p->mark_clone(
false);
183 uinsert =
umap_.emplace(
p->underlying_id(), upod);
186 if(!uinsert.second) {
187 throw game::error(
"One million collisions in unit_map");
192 std::pair<lmap::iterator, bool> linsert =
lmap_.emplace(loc, uinsert.first);
195 if(!linsert.second) {
198 umap_.erase(uinsert.first);
201 uinsert.first->second.unit.reset();
204 DBG_NG <<
"Trying to add " <<
p->name() <<
" - " <<
p->id() <<
" at location (" << loc <<
"); Occupied by "
205 << (linsert.first->second->second).
unit->
name() <<
" - " << linsert.first->second->second.unit->id()
227 umap::const_iterator ui =
umap_.begin();
228 umap::const_iterator uend =
umap_.end();
230 for(; ui != uend; ++ui) {
231 if(ui->second.ref_count < 0) {
233 bool a_reference_counter_overflowed(
false);
234 assert(a_reference_counter_overflowed);
249 DBG_NG <<
"Delete unit " <<
i->second.unit->underlying_id();
250 i->second.unit.reset();
270 std::size_t uid(u->underlying_id());
272 DBG_NG <<
"Extract unit " << uid <<
" - " << u->id() <<
" from location: (" << loc <<
")";
274 assert(uit->first == uit->second.unit->underlying_id());
275 if(uit->second.ref_count == 0) {
279 uit->second.unit.reset();
306 if((
i !=
umap_.end()) && !
i->second.unit) {
310 return make_unit_iterator<umap::iterator>(
i);
316 return make_unit_iterator<lmap::iterator>(
lmap_.find(loc));
322 for(;
i != i_end; ++
i) {
323 if(
i->side() == side &&
i->can_recruit()) {
336 for(;
i != i_end; ++
i) {
337 if(
i->side() == side &&
i->can_recruit()) {
338 if((first_leader ==
end()) || (
i->underlying_id() < first_leader->underlying_id())) {
351 std::vector<unit_map::unit_iterator> leaders;
352 for(;
i != i_end; ++
i) {
353 if(
i->side() == side &&
i->can_recruit()) {
354 leaders.push_back(
i);
363 const std::vector<unit_map::unit_iterator>& leaders =
const_cast<unit_map*
>(
this)->
find_leaders(side);
364 std::vector<unit_map::const_unit_iterator> const_leaders(leaders.begin(), leaders.end());
366 return const_leaders;
371 #ifdef DEBUG_UNIT_MAP
374 umap::const_iterator uit(
umap_.begin());
375 for(; uit !=
umap_.end(); ++uit) {
376 if(uit->second.ref_count < 0) {
378 ERR_NG <<
"unit_map pod ref_count <0 is " << uit->second.ref_count;
381 if(uit->second.unit) {
382 uit->second.unit->id();
385 if(uit->first <= 0) {
387 ERR_NG <<
"unit_map umap uid <=0 is " << uit->first;
390 if(!uit->second.unit && uit->second.ref_count == 0) {
392 ERR_NG <<
"unit_map umap unit==nullptr when refcount == 0";
395 if(uit->second.unit && uit->second.unit->underlying_id() != uit->first) {
397 ERR_NG <<
"unit_map umap uid(" << uit->first <<
") != underlying_id()[" << uit->second.unit->underlying_id()
402 lmap::const_iterator locit(
lmap_.begin());
403 for(; locit !=
lmap_.end(); ++locit) {
404 if(locit->second ==
umap_.end()) {
406 ERR_NG <<
"unit_map lmap element == umap_.end() ";
408 if(locit->first != locit->second->second.unit->get_location()) {
410 ERR_NG <<
"unit_map lmap location != unit->get_location() ";
425 for(
const umap::value_type&
item :
umap_) {
426 if(
item.second.unit.get() == u) {
Container associating units to locations.
umap::iterator begin_core() const
std::vector< unit_iterator > find_leaders(int side)
umap umap_
underlying_id -> unit_pod.
bool has_unit_at(const map_location &loc) const
Tests whether a unit exists at the given location.
std::pair< unit_iterator, bool > umap_retval_pair_t
bool self_check() const
Checks invariants.
void clear(bool force=false)
unit_ptr extract(const map_location &loc)
Extracts a unit from the map.
umap_retval_pair_t replace(const map_location &l, unit_ptr p)
Works like unit_map::add; but l is emptied first, if needed.
unit_iterator find(std::size_t id)
unit_map & operator=(const unit_map &that)
unit_map::unit_iterator make_unit_iterator(const X &i)
std::size_t num_iters() const
unit_iterator find_first_leader(int side)
lmap lmap_
location -> umap::iterator.
bool has_unit(const unit *const u) const
Is the unit in the map?
std::size_t erase(const map_location &l)
Erases the unit at location l, if any.
umap_retval_pair_t add(const map_location &l, const unit &u)
Adds a copy of unit u at location l of the map.
unit_iterator find_leader(int side)
umap_retval_pair_t insert(unit_ptr p)
Inserts the unit pointed to by p into the map.
bool is_valid(const umap::const_iterator &i) const
umap_retval_pair_t move(const map_location &src, const map_location &dst)
Moves a unit from location src to location dst.
This class represents a single unit of a specific type.
const t_string & name() const
Gets this unit's translatable display name.
Standard logging facilities (interface).
std::pair< std::string, unsigned > item
std::string::const_iterator iterator
std::shared_ptr< unit > unit_ptr
Base class for all the errors encountered by the engine.
Encapsulates the map of the game.
The pointer to the unit and a reference counter to record the number of extant iteratorspointing to t...
n_ref_counter::ref_counter< signed int > ref_count
void swap(unit_map &lhs, unit_map &rhs)
Implement non-member swap function for std::swap (calls unit_map::swap).
static lg::log_domain log_engine("engine")