The Battle for Wesnoth  1.15.12+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 
25 {
27 }
29  : unit_(ptr.unit_)
30  , my_manager_(nullptr)
31 {}
32 
34  : unit_(std::move(ptr.unit_))
36 {
37  ptr.my_manager_ = nullptr;
38 }
39 
41  std::swap(unit_, o.unit_);
43 }
44 
46  swap(other);
47  return *this;
48 }
49 
50 
51 /**
52  * Assignment operator, taking a unit.
53  * If already in the queue, @a this will be moved to the end of the
54  * queue (drawn last).
55  *
56  * This function is unsuitable for derived classes and MUST be overridden.
57  * Furthermore, derived classes must not explicitly call this version.
58  *
59  * The overriding function can be almost the same, except "new (this)" should
60  * be followed by the derived class instead of "fake_unit(a)".
61  */
62 /*fake_unit & fake_unit::operator=(const unit& a)
63 {
64  if ( this != &a ) {
65  fake_unit_manager * mgr = my_manager_;
66 
67  // Use the copy constructor to make sure we are coherent.
68  // (Methodology copied from unit::operator=)
69  this->~fake_unit();
70  new (this) fake_unit(a);
71  // Restore our old manager.
72  if ( mgr != nullptr )
73  place_on_fake_unit_manager(mgr);
74  }
75  return *this;
76 }*/
77 
78 /**
79  * Removes the unit from the fake manager, and resets the internal unit pointer.
80  * After this, both pointers are null.
81  */
83 {
85  unit_.reset();
86 }
87 
88 /**
89  * Resets the internal unit pointer to match the given pointer.
90  * The value of my_manager_ is preserved -- the old unit is deregistered,
91  * and the new unit is registered with the same manager.
92  */
94 {
95  if (unit_.get() != ptr.get()) {
97 
99  unit_ = ptr;
100  if (mgr)
102  }
103 }
104 
105 /**
106  * Removes @a this from the fake_units_ list if necessary.
107  */
109 {
110  try {
111  // The fake_unit class exists for this one line, which removes the
112  // fake_unit from the managers's fake_units_ dequeue in the event of an
113  // exception.
114  if(my_manager_) {
115  //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
116  if(resources::fake_units != nullptr) {
118  }
119  }
120 
121  } catch (...) {}
122 }
123 
124 /**
125  * Place @a this on @a manager's fake_units_ dequeue.
126  * This will be added at the end (drawn last, over all other units).
127  * Duplicate additions are not allowed.
128  */
130  assert(my_manager_ == nullptr); //Can only be placed on 1 fake_unit_manager
131  my_manager_=manager;
133 }
134 
135 /**
136  * Removes @a this from whatever fake_units_ list it is on (if any).
137  * @returns the number of fake_units deleted, which should be 0 or 1
138  * (any other number indicates an error).
139  */
141  int ret(0);
142  if(my_manager_ != nullptr){
144  my_manager_=nullptr;
145  }
146  return ret;
147 }
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:30
void swap(config &lhs, config &rhs)
Implement non-member swap function for std::swap (calls config::swap).
Definition: config.cpp:1431
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.