New implementation of modification_queue...
...that preserves order when priorities are equal. Fixes bug #20196.
This commit is contained in:
parent
9c63d717cc
commit
52ae1ea735
3 changed files with 64 additions and 19 deletions
|
@ -44,6 +44,7 @@ Version 1.11.0+svn:
|
|||
* Added [terrain_type] max_light= and min_light=.
|
||||
* Standardize weapon filters, supporting special=, [and], [or], and [not]
|
||||
wherever weapons can be filtered.
|
||||
* Image path functions again evaluated left-to-right. Fixes bug #20196.
|
||||
* Miscellaneous and bug fixes:
|
||||
* Fix invalid memory access crash resulting from deleting all saved games
|
||||
in the Load Game dialog
|
||||
|
|
|
@ -35,6 +35,43 @@ static lg::log_domain log_display("display");
|
|||
namespace image {
|
||||
|
||||
|
||||
/** Adds @a mod to the queue (unless mod is NULL). */
|
||||
void modification_queue::push(modification * mod)
|
||||
{
|
||||
// Null pointers do not get stored. (Shouldn't happen, but just in case.)
|
||||
if ( mod != NULL )
|
||||
priorities_[mod->priority()].push_back(mod);
|
||||
}
|
||||
|
||||
/** Removes the top element from the queue */
|
||||
void modification_queue::pop()
|
||||
{
|
||||
map_type::iterator top_pair = priorities_.begin();
|
||||
std::vector<modification *> & top_vector = top_pair->second;
|
||||
|
||||
// Erase the top element.
|
||||
top_vector.erase(top_vector.begin());
|
||||
if ( top_vector.empty() )
|
||||
// We need to keep the map clean.
|
||||
priorities_.erase(top_pair);
|
||||
}
|
||||
|
||||
/** Returns the number of elements in the queue. */
|
||||
size_t modification_queue::size() const
|
||||
{
|
||||
size_t count = 0;
|
||||
BOOST_FOREACH ( const map_type::value_type & pair, priorities_ )
|
||||
count += pair.second.size();
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Returns the top element in the queue . */
|
||||
modification * modification_queue::top() const
|
||||
{
|
||||
return priorities_.begin()->second.front();
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
/// A function used to parse modification arguments
|
||||
|
@ -113,13 +150,6 @@ modification_queue modification::decode(const std::string& encoded_mods)
|
|||
return mods;
|
||||
}
|
||||
|
||||
/// Compares two modification pointers, providing descending priority order
|
||||
bool mod_ptr_comparator_::operator()(const modification* a,
|
||||
const modification* b) const
|
||||
{
|
||||
return a->priority() < b->priority();
|
||||
}
|
||||
|
||||
surface rc_modification::operator()(const surface& src) const
|
||||
{
|
||||
// unchecked
|
||||
|
|
|
@ -24,11 +24,32 @@
|
|||
namespace image {
|
||||
|
||||
class modification;
|
||||
struct mod_ptr_comparator_;
|
||||
/// A priority queue used to enforce using the rc modifications first
|
||||
typedef std::priority_queue<modification*,
|
||||
std::vector<modification*>,
|
||||
mod_ptr_comparator_> modification_queue;
|
||||
|
||||
|
||||
/// A modified priority queue used to order image modifications.
|
||||
/// The priorities for this queue are to order modifications by priority(),
|
||||
/// then by the order they are added to the queue.
|
||||
class modification_queue {
|
||||
// Invariant for this class:
|
||||
// At the beginning and end of each member function call, there
|
||||
// are no empty vectors in priorities_.
|
||||
public:
|
||||
modification_queue() {}
|
||||
~modification_queue() {}
|
||||
|
||||
bool empty() const { return priorities_.empty(); }
|
||||
void push(modification * mod);
|
||||
void pop();
|
||||
size_t size() const;
|
||||
modification * top() const;
|
||||
|
||||
private: // data
|
||||
/// Map from a mod's priority() to the mods having that priority.
|
||||
typedef std::map<int, std::vector<modification *>, std::greater<int> > map_type;
|
||||
/// Map from a mod's priority() to the mods having that priority.
|
||||
map_type priorities_;
|
||||
};
|
||||
|
||||
|
||||
/// Base abstract class for an image-path modification
|
||||
class modification
|
||||
|
@ -81,13 +102,6 @@ public:
|
|||
virtual int priority() const { return 0; }
|
||||
};
|
||||
|
||||
/// A functor for comparing modification pointers
|
||||
struct mod_ptr_comparator_
|
||||
{
|
||||
/// Provides a descending priority ordering
|
||||
bool operator()(const modification* a, const modification* b) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Recolor (RC/TC/PAL) modification.
|
||||
* It is used not only for color-range-based recoloring ("~RC(magenta>teal)")
|
||||
|
|
Loading…
Add table
Reference in a new issue