mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-22 16:00:25 +00:00
91 lines
3.2 KiB
C++
91 lines
3.2 KiB
C++
/*
|
|
Copyright (C) 2014 - 2024
|
|
by Chris Beck <render787@gmail.com>
|
|
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY.
|
|
|
|
See the COPYING file for more details.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "units/ptr.hpp"
|
|
|
|
class fake_unit_manager;
|
|
|
|
/** Holds a temporary unit that can be drawn on the map without
|
|
being placed in the unit_map.
|
|
Temporary units can overlap units.
|
|
They are drawn after the normal units, and so draw over them.
|
|
Adding the same unit twice isn't allowed.
|
|
The fake_unit privately holds a referenced counted point to its underlying unit,
|
|
when it goes out of scope it removes the entry from the fake_units list.
|
|
The intent is to provide exception safety when the code
|
|
creating the temp unit is unexpectedly forced out of scope.
|
|
*/
|
|
class fake_unit_ptr {
|
|
public:
|
|
typedef unit_ptr internal_ptr;
|
|
typedef unit_const_ptr internal_const_ptr;
|
|
|
|
fake_unit_ptr();
|
|
/** Construct a fake unit pointer wrapping a normal unit pointer, marking it as a fake unit. */
|
|
explicit fake_unit_ptr(const internal_ptr & u);
|
|
/** Construct a fake unit pointer, and simultaenously register with a manager. */
|
|
fake_unit_ptr(const internal_ptr & u, fake_unit_manager * mgr);
|
|
/** Copy construct a fake unit pointer. Does not reallocate the underlying unit. */
|
|
fake_unit_ptr(const fake_unit_ptr & ptr);
|
|
fake_unit_ptr(fake_unit_ptr && ptr);
|
|
|
|
/** Pointer swap. */
|
|
void swap (fake_unit_ptr & o);
|
|
|
|
/** Copy assignment operator using copy-and-swap idiom */
|
|
fake_unit_ptr & operator=(fake_unit_ptr other);
|
|
|
|
/** Reset the internal unit pointer, and deregister from the manager. This fake_unit_ptr is now dissassociated from the manager. */
|
|
void reset();
|
|
/** Reset the internal unit pointer and point to a new unit. The old unit is deregistered, and the new unit is registered with the old manager, if there was one. */
|
|
void reset(const internal_ptr & ptr);
|
|
|
|
/** Dereference the internal unit pointer. */
|
|
internal_ptr operator->() { return unit_; }
|
|
/** Dereference the internal unit pointer. */
|
|
internal_const_ptr operator->() const { return unit_; }
|
|
|
|
/** Get a copy of the internal unit pointer. */
|
|
internal_ptr get_unit_ptr() { return unit_; }
|
|
/** Get a copy of the internal unit pointer. */
|
|
internal_const_ptr get_unit_ptr() const { return unit_; }
|
|
|
|
/** Derference the internal unit pointer. */
|
|
unit & operator*() { return *unit_; }
|
|
/** Get a raw pointer to the underlying unit. */
|
|
unit * get() { return unit_.get(); }
|
|
|
|
/** Removes @a this from the fake_units_ list if necessary. */
|
|
~fake_unit_ptr();
|
|
|
|
/** Place @a this on @a manager's fake_units_ dequeue. */
|
|
void place_on_fake_unit_manager(fake_unit_manager * d);
|
|
/** Removes @a this from whatever fake_units_ list it is on (if any). */
|
|
int remove_from_fake_unit_manager();
|
|
|
|
private :
|
|
/** Internal unit pointer. */
|
|
internal_ptr unit_;
|
|
/** Raw pointer to the manager. */
|
|
fake_unit_manager * my_manager_;
|
|
|
|
public:
|
|
|
|
explicit operator bool() const
|
|
{ return unit_.get() != nullptr; }
|
|
};
|