The Battle for Wesnoth  1.17.0-dev
fake_unit_ptr.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2021
3  by Chris Beck <render787@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "fake_unit_ptr.hpp"
17 
18 #include "fake_unit_manager.hpp"
19 #include "resources.hpp"
20 #include "units/unit.hpp"
21 #include "units/ptr.hpp"
22 
26 {
28 }
30  : unit_(ptr.unit_)
31  , my_manager_(nullptr)
32 {}
33 
35  : unit_(std::move(ptr.unit_))
37 {
38  ptr.my_manager_ = nullptr;
39 }
40 
42  std::swap(unit_, o.unit_);
44 }
45 
47  swap(other);
48  return *this;
49 }
50 
51 
52 /**
53  * Assignment operator, taking a unit.
54  * If already in the queue, @a this will be moved to the end of the
55  * queue (drawn last).
56  *
57  * This function is unsuitable for derived classes and MUST be overridden.
58  * Furthermore, derived classes must not explicitly call this version.
59  *
60  * The overriding function can be almost the same, except "new (this)" should
61  * be followed by the derived class instead of "fake_unit(a)".
62  */
63 /*fake_unit & fake_unit::operator=(const unit& a)
64 {
65  if ( this != &a ) {
66  fake_unit_manager * mgr = my_manager_;
67 
68  // Use the copy constructor to make sure we are coherent.
69  // (Methodology copied from unit::operator=)
70  this->~fake_unit();
71  new (this) fake_unit(a);
72  // Restore our old manager.
73  if ( mgr != nullptr )
74  place_on_fake_unit_manager(mgr);
75  }
76  return *this;
77 }*/
78 
79 /**
80  * Removes the unit from the fake manager, and resets the internal unit pointer.
81  * After this, both pointers are null.
82  */
84 {
86  unit_.reset();
87 }
88 
89 /**
90  * Resets the internal unit pointer to match the given pointer.
91  * The value of my_manager_ is preserved -- the old unit is deregistered,
92  * and the new unit is registered with the same manager.
93  */
95 {
96  if (unit_.get() != ptr.get()) {
98 
100  unit_ = ptr;
101  if (mgr)
103  }
104 }
105 
106 /**
107  * Removes @a this from the fake_units_ list if necessary.
108  */
110 {
111  try {
112  // The fake_unit class exists for this one line, which removes the
113  // fake_unit from the managers's fake_units_ dequeue in the event of an
114  // exception.
115  if(my_manager_) {
116  //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
117  if(resources::fake_units != nullptr) {
119  }
120  }
121 
122  } catch (...) {}
123 }
124 
125 /**
126  * Place @a this on @a manager's fake_units_ dequeue.
127  * This will be added at the end (drawn last, over all other units).
128  * Duplicate additions are not allowed.
129  */
131  assert(my_manager_ == nullptr); //Can only be placed on 1 fake_unit_manager
132  my_manager_=manager;
134 }
135 
136 /**
137  * Removes @a this from whatever fake_units_ list it is on (if any).
138  * @returns the number of fake_units deleted, which should be 0 or 1
139  * (any other number indicates an error).
140  */
142  int ret(0);
143  if(my_manager_ != nullptr){
145  my_manager_=nullptr;
146  }
147  return ret;
148 }
void reset()
Reset the internal unit pointer, and deregister from the manager.
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:31
void swap(config &lhs, config &rhs)
Implement non-member swap function for std::swap (calls config::swap).
Definition: config.cpp:1456
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.