diff --git a/src/image.cpp b/src/image.cpp index 06c1cae5d78..2e29a36ff2f 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -36,12 +36,87 @@ #include +#include #include static lg::log_domain log_display("display"); #define ERR_DP LOG_STREAM(err, log_display) #define LOG_DP LOG_STREAM(info, log_display) +/** + * Iterators from this dummy list are needed to ensure that iterator member + * of cache_item is always non-singular iterator thus avoiding + * "Copy-contruct from singular iterator" error when libstdc++ debug mode + * is enabled. Note copying a singular iterator is undefined behaviour by + * the C++ standard. + */ +static std::list dummy_list; + +template +struct cache_item +{ + cache_item(): loaded(false), item(), position(dummy_list.end()) + { + } + + cache_item(const T &item): loaded(true), item(item), position(dummy_list.end()) + { + } + + bool loaded; + T item; + std::list::iterator position; +}; + +namespace image { + +template +class cache_type +{ +public: + cache_type(): cache_size_(0), cache_max_size_(2000), lru_list_(), content_() + { + } + + cache_item &get_element(int index); + void on_load(int index); + + void flush() + { + content_.clear(); + lru_list_.clear(); + cache_size_ = 0; + } + +private: + int cache_size_; + int cache_max_size_; + std::list lru_list_; + std::vector > content_; +}; + +template +bool locator::in_cache(cache_type &cache) const +{ + return index_ == -1 ? false : cache.get_element(index_).loaded; +} + +template +const T &locator::locate_in_cache(cache_type &cache) const +{ + static T dummy; + return index_ == -1 ? dummy : cache.get_element(index_).item; +} + +template +void locator::add_to_cache(cache_type &cache, const T &data) const +{ + if (index_ != -1 ) cache.get_element(index_) = cache_item(data); + cache.on_load(index_); +} + +} + namespace { image::locator::locator_finder_t locator_finder; @@ -76,20 +151,11 @@ namespace image { std::list dummy_list; -template -void cache_type::flush() -{ - typename std::vector >::iterator beg = content_.begin(); - typename std::vector >::iterator end = content_.end(); - - for(; beg != end; ++beg) { - beg->loaded = false; - beg->item = T(); - } -} mini_terrain_cache_map mini_terrain_cache; mini_terrain_cache_map mini_fogged_terrain_cache; +static int last_index_ = 0; + void flush_cache() { images_.flush(); @@ -105,10 +171,9 @@ void flush_cache() reversed_images_.clear(); image_existence_map.clear(); precached_dirs.clear(); + last_index_ = 0; } -int locator::last_index_ = 0; - void locator::init_index() { std::map& finder = locator_finder[hash_value(val_)]; @@ -1115,11 +1180,10 @@ bool precached_file_exists(const std::string& file) } template -cache_item& cache_type::get_element(int index){ +cache_item& cache_type::get_element(int index) +{ assert (index != -1); - while(static_cast(index) >= content_.size()) { - content_.push_back(cache_item()); - } + if (unsigned(index) >= content_.size()) content_.resize(index + 1); cache_item& elt = content_[index]; if(elt.loaded) { assert(*elt.position == index); diff --git a/src/image.hpp b/src/image.hpp index 37722ada80d..31e490e74e2 100644 --- a/src/image.hpp +++ b/src/image.hpp @@ -20,12 +20,10 @@ #include "terrain_translation.hpp" #include "SDL.h" -#include "cassert" #include #include #include -#include ///this module manages the cache of images. With an image name, you can get ///the surface corresponding to that image. @@ -43,57 +41,9 @@ namespace image { #else const int tile_size = 72; #endif - /** - * Iterators from this dummy list are needed to ensure that iterator member - * of cache_item is always non-singular iterator thus avoiding - * "Copy-contruct from singular iterator" error when libstdc++ debug mode - * is enabled. Note copying a singular iterator is undefined behaviour by - * the C++ standard. - */ - extern std::list dummy_list; template - struct cache_item { - cache_item() : - loaded(false), - item() , - position(dummy_list.end()) - { - } - - cache_item(T item) : - loaded(true), - item(item), - position(dummy_list.end()) - { - } - - bool loaded; - T item; - std::list::iterator position; - }; - - template - class cache_type - { - public: - cache_type() : - cache_size_(0), - cache_max_size_(2000), - lru_list_(), - content_() - { - } - - cache_item& get_element(int index); - void on_load(int index); - void flush(); - private: - int cache_size_; - int cache_max_size_; - std::list lru_list_; - std::vector > content_; - }; + class cache_type; //a generic image locator. Abstracts the location of an image. class locator @@ -178,17 +128,12 @@ namespace image { surface load_from_disk() const; template - bool in_cache(cache_type& cache) const - { return index_ == -1 ? false : cache.get_element(index_).loaded; } + bool in_cache(cache_type &cache) const; template - T locate_in_cache(cache_type& cache) const - { return index_ == -1 ? T() : cache.get_element(index_).item; } + const T &locate_in_cache(cache_type &cache) const; template - void add_to_cache(cache_type& cache, const T &data) const - { if(index_ != -1 ) cache.get_element(index_) = cache_item(data); cache.on_load(index_); } + void add_to_cache(cache_type &cache, const T &data) const; - protected: - static int last_index_; private: surface load_image_file() const; diff --git a/src/reports.cpp b/src/reports.cpp index 773a60a7140..55f8dfc6c05 100644 --- a/src/reports.cpp +++ b/src/reports.cpp @@ -16,6 +16,7 @@ #include "reports.hpp" +#include namespace { const std::string report_names[] = {