The Battle for Wesnoth  1.15.2+dev
fake_unit_ptr.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2018 by Chris Beck <render787@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "fake_unit_ptr.hpp"
16 
17 #include "fake_unit_manager.hpp"
18 #include "resources.hpp"
19 #include "units/unit.hpp"
20 #include "units/ptr.hpp"
21 
22 #include <boost/swap.hpp>
23 
27 {
29 }
31  : unit_(ptr.unit_)
32  , my_manager_(nullptr)
33 {}
34 
36  : unit_(std::move(ptr.unit_))
38 {
39  ptr.my_manager_ = nullptr;
40 }
41 
45 }
46 
48  swap(other);
49  return *this;
50 }
51 
52 
53 /**
54  * Assignment operator, taking a unit.
55  * If already in the queue, @a this will be moved to the end of the
56  * queue (drawn last).
57  *
58  * This function is unsuitable for derived classes and MUST be overridden.
59  * Furthermore, derived classes must not explicitly call this version.
60  *
61  * The overriding function can be almost the same, except "new (this)" should
62  * be followed by the derived class instead of "fake_unit(a)".
63  */
64 /*fake_unit & fake_unit::operator=(const unit& a)
65 {
66  if ( this != &a ) {
67  fake_unit_manager * mgr = my_manager_;
68 
69  // Use the copy constructor to make sure we are coherent.
70  // (Methodology copied from unit::operator=)
71  this->~fake_unit();
72  new (this) fake_unit(a);
73  // Restore our old manager.
74  if ( mgr != nullptr )
75  place_on_fake_unit_manager(mgr);
76  }
77  return *this;
78 }*/
79 
80 /**
81  * Removes the unit from the fake manager, and resets the internal unit pointer.
82  * After this, both pointers are null.
83  */
85 {
87  unit_.reset();
88 }
89 
90 /**
91  * Resets the internal unit pointer to match the given pointer.
92  * The value of my_manager_ is preserved -- the old unit is deregistered,
93  * and the new unit is registered with the same manager.
94  */
96 {
97  if (unit_.get() != ptr.get()) {
99 
101  unit_ = ptr;
102  if (mgr)
104  }
105 }
106 
107 /**
108  * Removes @a this from the fake_units_ list if necessary.
109  */
111 {
112  try {
113  // The fake_unit class exists for this one line, which removes the
114  // fake_unit from the managers's fake_units_ dequeue in the event of an
115  // exception.
116  if(my_manager_) {
117  //my_manager_ points to resources::fake_units, the next line fixes a bug whre this code would attempt to access a freed fake_unit_manager object, see https://github.com/wesnoth/wesnoth/issues/3008
118  if(resources::fake_units != nullptr) {
120  }
121  }
122 
123  } catch (...) {}
124 }
125 
126 /**
127  * Place @a this on @a manager's fake_units_ dequeue.
128  * This will be added at the end (drawn last, over all other units).
129  * Duplicate additions are not allowed.
130  */
132  assert(my_manager_ == nullptr); //Can only be placed on 1 fake_unit_manager
133  my_manager_=manager;
135 }
136 
137 /**
138  * Removes @a this from whatever fake_units_ list it is on (if any).
139  * @returns the number of fake_units deleted, which should be 0 or 1
140  * (any other number indicates an error).
141  */
143  int ret(0);
144  if(my_manager_ != nullptr){
146  my_manager_=nullptr;
147  }
148  return ret;
149 }
void reset()
Reset the internal unit pointer, and deregister from the manager. This fake_unit_ptr is now dissassoc...
void place_on_fake_unit_manager(fake_unit_manager *d)
Place this on manager&#39;s fake_units_ dequeue.
Manages a list of fake units for the display object.
int remove_from_fake_unit_manager()
Removes this from whatever fake_units_ list it is on (if any).
STL namespace.
fake_unit_manager * my_manager_
Raw pointer to the manager.
int remove_temporary_unit(internal_ptr_type)
Deregister a unit from this manager.
const unit * unit_
~fake_unit_ptr()
Removes this from the fake_units_ list if necessary.
internal_ptr unit_
Internal unit pointer.
fake_unit_manager * fake_units
Definition: resources.cpp:30
void swap(config &lhs, config &rhs)
Implement non-member swap function for std::swap (calls config::swap).
Definition: config.cpp:1386
void swap(fake_unit_ptr &o)
Pointer swap.
void place_temporary_unit(internal_ptr_type)
Register a unit with this manager.
unit_ptr internal_ptr
fake_unit_ptr & operator=(fake_unit_ptr other)
Copy assignment operator using copy-and-swap idiom.
Holds a temporary unit that can be drawn on the map without being placed in the unit_map.