Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/src/dialogs.cpp b/src/dialogs.cpp
- index ba99d03..efb93cb 100644
- --- a/src/dialogs.cpp
- +++ b/src/dialogs.cpp
- @@ -272,13 +272,13 @@ namespace {
- class delete_save : public gui::dialog_button_action
- {
- public:
- - delete_save(display& disp, gui::filter_textbox& filter, std::vector<savegame::save_info>& saves, std::vector<config*>& save_summaries) : disp_(disp), saves_(saves), summaries_(save_summaries), filter_(filter) {}
- + delete_save(display& disp, gui::filter_textbox& filter, std::vector<savegame::save_info>& saves) :
- + disp_(disp), saves_(saves), filter_(filter) {}
- private:
- gui::dialog_button_action::RESULT button_pressed(int menu_selection);
- display& disp_;
- std::vector<savegame::save_info>& saves_;
- - std::vector<config*>& summaries_;
- gui::filter_textbox& filter_;
- };
- @@ -298,15 +298,11 @@ gui::dialog_button_action::RESULT delete_save::button_pressed(int menu_selection
- filter_.delete_item(menu_selection);
- // Delete the file
- - savegame::manager::delete_game(saves_[index].name);
- + savegame::delete_game(saves_[index].name());
- // Remove it from the list of saves
- saves_.erase(saves_.begin() + index);
- - if(index < summaries_.size()) {
- - summaries_.erase(summaries_.begin() + index);
- - }
- -
- return gui::DELETE_ITEM;
- } else {
- return gui::CONTINUE_DIALOG;
- @@ -320,12 +316,10 @@ class save_preview_pane : public gui::preview_pane
- public:
- save_preview_pane(CVideo &video, const config& game_config, gamemap* map,
- const std::vector<savegame::save_info>& info,
- - const std::vector<config*>& summaries,
- const gui::filter_textbox& textbox) :
- gui::preview_pane(video),
- game_config_(&game_config),
- map_(map), info_(&info),
- - summaries_(summaries),
- index_(0),
- map_cache_(),
- textbox_(textbox)
- @@ -346,7 +340,6 @@ private:
- const config* game_config_;
- gamemap* map_;
- const std::vector<savegame::save_info>* info_;
- - const std::vector<config*>& summaries_;
- int index_;
- std::map<std::string,surface> map_cache_;
- const gui::filter_textbox& textbox_;
- @@ -354,21 +347,6 @@ private:
- void save_preview_pane::draw_contents()
- {
- - if (size_t(index_) >= summaries_.size() || info_->size() != summaries_.size()) {
- - return;
- - }
- -
- - std::string dummy;
- - const config &summary = *summaries_[index_];
- - if (summary["label"].empty())
- - {
- - try {
- - savegame::manager::load_summary((*info_)[index_].name, *summaries_[index_], &dummy);
- - } catch(game::load_game_failed&) {
- - (*summaries_[index_])["corrupt"] = true;
- - }
- - }
- -
- surface screen = video().getSurface();
- SDL_Rect const &loc = location();
- @@ -381,6 +359,7 @@ void save_preview_pane::draw_contents()
- int ypos = area.y;
- + const config& summary= ((*info_)[index_]).summary();
- const unit_type *leader = unit_types.find(summary["leader"]);
- if (leader)
- {
- @@ -448,7 +427,7 @@ void save_preview_pane::draw_contents()
- char time_buf[256] = {0};
- const savegame::save_info& save = (*info_)[index_];
- - tm* tm_l = localtime(&save.time_modified);
- + tm* tm_l = localtime(&save.modified());
- if (tm_l) {
- const size_t res = strftime(time_buf,sizeof(time_buf),
- (preferences::use_twelve_hour_clock_format() ? _("%a %b %d %I:%M %p %Y") : _("%a %b %d %H:%M %Y")),
- @@ -457,13 +436,13 @@ void save_preview_pane::draw_contents()
- time_buf[0] = 0;
- }
- } else {
- - LOG_NG << "localtime() returned null for time " << save.time_modified << ", save " << save.name;
- + LOG_NG << "localtime() returned null for time " << save.modified() << ", save " << save.name();
- }
- std::stringstream str;
- str << font::BOLD_TEXT << font::NULL_MARKUP
- - << (*info_)[index_].name << '\n' << time_buf;
- + << (*info_)[index_].name() << '\n' << time_buf;
- const std::string& campaign_type = summary["campaign_type"];
- if (summary["corrupt"].to_bool()) {
- @@ -582,7 +561,7 @@ std::string load_game_dialog(display& disp, const config& game_config, bool* sho
- std::vector<savegame::save_info> games;
- {
- cursor::setter cur(cursor::WAIT);
- - games = savegame::manager::get_saves_list();
- + games = savegame::get_saves_list();
- }
- if(games.empty()) {
- @@ -592,29 +571,19 @@ std::string load_game_dialog(display& disp, const config& game_config, bool* sho
- return "";
- }
- - std::vector<config*> summaries;
- - std::vector<savegame::save_info>::const_iterator i;
- - //FIXME: parent_to_child is not used yet
- - std::map<std::string,std::string> parent_to_child;
- - for(i = games.begin(); i != games.end(); ++i) {
- - config& cfg = savegame::save_index::save_summary(i->name);
- - parent_to_child[cfg["parent"]] = i->name;
- - summaries.push_back(&cfg);
- - }
- -
- const events::event_context context;
- std::vector<std::string> items;
- std::ostringstream heading;
- heading << HEADING_PREFIX << _("Name") << COLUMN_SEPARATOR << _("Date");
- items.push_back(heading.str());
- -
- + std::vector<savegame::save_info>::const_iterator i;
- for(i = games.begin(); i != games.end(); ++i) {
- - std::string name = i->name;
- + std::string name = i->name();
- utils::truncate_as_wstring(name, std::min<size_t>(name.size(), 40));
- std::ostringstream str;
- - str << name << COLUMN_SEPARATOR << format_time_summary(i->time_modified);
- + str << name << COLUMN_SEPARATOR << format_time_summary(i->modified());
- items.push_back(str.str());
- }
- @@ -634,7 +603,7 @@ std::string load_game_dialog(display& disp, const config& game_config, bool* sho
- gui::filter_textbox* filter = new gui::filter_textbox(disp.video(), _("Filter: "), items, items, 1, lmenu);
- lmenu.set_textbox(filter);
- - save_preview_pane save_preview(disp.video(),game_config,&map_obj,games,summaries,*filter);
- + save_preview_pane save_preview(disp.video(),game_config,&map_obj,games,*filter);
- lmenu.add_pane(&save_preview);
- // create an option for whether the replay should be shown or not
- if(show_replay != NULL) {
- @@ -652,7 +621,7 @@ std::string load_game_dialog(display& disp, const config& game_config, bool* sho
- lmenu.add_button(new gui::standard_dialog_button(disp.video(),_("OK"),0,false), gui::dialog::BUTTON_STANDARD);
- lmenu.add_button(new gui::standard_dialog_button(disp.video(),_("Cancel"),1,true), gui::dialog::BUTTON_STANDARD);
- - delete_save save_deleter(disp,*filter,games,summaries);
- + delete_save save_deleter(disp,*filter,games);
- gui::dialog_button_info delete_button(&save_deleter,_("Delete Save"));
- lmenu.add_button(delete_button,
- @@ -662,8 +631,6 @@ std::string load_game_dialog(display& disp, const config& game_config, bool* sho
- int res = lmenu.show();
- - savegame::save_index::write_save_index();
- -
- if(res == -1)
- return "";
- @@ -672,7 +639,7 @@ std::string load_game_dialog(display& disp, const config& game_config, bool* sho
- if(show_replay != NULL) {
- *show_replay = lmenu.option_checked(option_index++);
- - const config& summary = *summaries[res];
- + const config& summary = games[res].summary();
- if (summary["replay"].to_bool() && !summary["snapshot"].to_bool(true)) {
- *show_replay = true;
- }
- @@ -681,7 +648,7 @@ std::string load_game_dialog(display& disp, const config& game_config, bool* sho
- *cancel_orders = lmenu.option_checked(option_index++);
- }
- - return games[res].name;
- + return games[res].name();
- }
- namespace {
- diff --git a/src/gui/dialogs/data_manage.cpp b/src/gui/dialogs/data_manage.cpp
- index e908bc5..24c0c63 100644
- --- a/src/gui/dialogs/data_manage.cpp
- +++ b/src/gui/dialogs/data_manage.cpp
- @@ -83,7 +83,7 @@ void tdata_manage::pre_show(CVideo& /*video*/, twindow& window)
- {
- cursor::setter cur(cursor::WAIT);
- - games_ = savegame::manager::get_saves_list();
- + games_ = savegame::get_saves_list();
- }
- fill_game_list(window, games_);
- @@ -105,7 +105,7 @@ void tdata_manage::fill_game_list(twindow& window
- std::map<std::string, string_map> data;
- string_map item;
- - item["label"] = game.name;
- + item["label"] = game.name();
- data.insert(std::make_pair("filename", item));
- item["label"] = game.format_time_summary();
- @@ -179,7 +179,7 @@ void tdata_manage::delete_button_callback(twindow& window)
- }
- // Delete the file
- - savegame::manager::delete_game(games_[index].name);
- + savegame::delete_game(games_[index].name());
- // Remove it from the list of saves
- games_.erase(games_.begin() + index);
- diff --git a/src/gui/dialogs/game_load.cpp b/src/gui/dialogs/game_load.cpp
- index d071c22..6d5ee86 100644
- --- a/src/gui/dialogs/game_load.cpp
- +++ b/src/gui/dialogs/game_load.cpp
- @@ -133,7 +133,7 @@ void tgame_load::pre_show(CVideo& /*video*/, twindow& window)
- {
- cursor::setter cur(cursor::WAIT);
- - games_ = savegame::manager::get_saves_list();
- + games_ = savegame::get_saves_list();
- }
- fill_game_list(window, games_);
- @@ -157,7 +157,7 @@ void tgame_load::fill_game_list(twindow& window
- std::map<std::string, string_map> data;
- string_map item;
- - item["label"] = game.name;
- + item["label"] = game.name();
- data.insert(std::make_pair("filename", item));
- item["label"] = game.format_time_summary();
- @@ -239,28 +239,21 @@ void tgame_load::display_savegame(twindow& window)
- preview_pane.set_visible(twidget::VISIBLE);
- savegame::save_info& game = games_[selected_row];
- - filename_ = game.name;
- + filename_ = game.name();
- - config cfg_summary;
- - std::string dummy;
- -
- - try {
- - savegame::manager::load_summary(game.name, cfg_summary, &dummy);
- - } catch(game::load_game_failed&) {
- - cfg_summary["corrupt"] = "yes";
- - }
- + const config& summary= game.summary();
- find_widget<timage>(&window, "imgLeader", false).
- - set_label(cfg_summary["leader_image"]);
- + set_label(summary["leader_image"]);
- find_widget<tminimap>(&window, "minimap", false).
- - set_map_data(cfg_summary["map_data"]);
- + set_map_data(summary["map_data"]);
- - find_widget<tlabel>(&window, "lblScenario", false).set_label(game.name);
- + find_widget<tlabel>(&window, "lblScenario", false).set_label(game.name());
- std::stringstream str;
- str << game.format_time_local();
- - evaluate_summary_string(str, cfg_summary);
- + evaluate_summary_string(str, summary);
- find_widget<tlabel>(&window, "lblSummary", false).set_label(str.str());
- @@ -344,7 +337,7 @@ void tgame_load::delete_button_callback(twindow& window)
- }
- // Delete the file
- - savegame::manager::delete_game(games_[index].name);
- + savegame::delete_game(games_[index].name());
- // Remove it from the list of saves
- games_.erase(games_.begin() + index);
- diff --git a/src/play_controller.cpp b/src/play_controller.cpp
- index 50d5cd9..9e21e45 100644
- --- a/src/play_controller.cpp
- +++ b/src/play_controller.cpp
- @@ -1103,7 +1103,7 @@ void play_controller::expand_autosaves(std::vector<std::string>& items)
- std::vector<std::string> newsaves;
- for (unsigned int turn = this->turn(); turn != 0; turn--) {
- std::string name = gamestate_.classification().label + "-" + _("Auto-Save") + lexical_cast<std::string>(turn);
- - if (savegame::manager::save_game_exists(name, preferences::compress_saves())) {
- + if (savegame::save_game_exists(name, preferences::compress_saves())) {
- if(preferences::compress_saves()) {
- newsaves.push_back(name + ".gz");
- } else {
- diff --git a/src/playcampaign.cpp b/src/playcampaign.cpp
- index 51bcea8..973a01a 100644
- --- a/src/playcampaign.cpp
- +++ b/src/playcampaign.cpp
- @@ -396,7 +396,7 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
- // need to change this test.
- if (res == VICTORY || (io_type != IO_NONE && res == DEFEAT)) {
- if (preferences::delete_saves())
- - savegame::manager::clean_saves(gamestate.classification().label);
- + savegame::clean_saves(gamestate.classification().label);
- if (preferences::save_replays() && end_level.replay_save) {
- savegame::replay_savegame save(gamestate, preferences::compress_saves());
- @@ -606,7 +606,7 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
- if (gamestate.classification().campaign_type == "scenario"){
- if (preferences::delete_saves())
- - savegame::manager::clean_saves(gamestate.classification().label);
- + savegame::clean_saves(gamestate.classification().label);
- }
- return VICTORY;
- }
- diff --git a/src/savegame.cpp b/src/savegame.cpp
- index 2a19dca..6fd5dcf 100644
- --- a/src/savegame.cpp
- +++ b/src/savegame.cpp
- @@ -132,9 +132,174 @@ static lg::log_domain log_engine("engine");
- namespace savegame {
- +class save_index_class
- +{
- +public:
- + void rebuild(const std::string& name) {
- + std::string filename= name;
- + replace_space2underbar(filename);
- + time_t modified= file_create_time(get_saves_dir() + "/" + filename);
- + rebuild(name, modified);
- + }
- + void rebuild(const std::string& name, const time_t& modified) {
- + log_scope("load_summary_from_file");
- + config& summary= data(name);
- + try {
- + config full;
- + std::string dummy;
- + read_save_file(name, full, &dummy);
- + ::extract_summary_from_config(full, summary);
- + } catch(game::load_game_failed&) {
- + summary["corrupt"] = true;
- + }
- + summary["mod_time"] = str_cast(static_cast<int>(modified));
- + write_save_index();
- + }
- + void set_modified(const std::string& name, const time_t& modified) {
- + modified_[name]= modified;
- + }
- + config& get(const std::string& name) {
- + config& result= data(name);
- + time_t m= modified_[name];
- + config::attribute_value& mod_time= result["mod_time"];
- + if (mod_time.empty() || static_cast<time_t>(mod_time.to_int()) != m) {
- + rebuild(name, m);
- + }
- + return result;
- + }
- +public:
- + void write_save_index() {
- + log_scope("write_save_index()");
- + try {
- + scoped_ostream stream = ostream_file(get_save_index_file());
- + if (preferences::compress_saves()) {
- + write_gz(*stream, data());
- + } else {
- + write(*stream, data());
- + }
- + } catch(io_exception& e) {
- + ERR_SAVE << "error writing to save index file: '" << e.what() << "'\n";
- + }
- + }
- +
- +public:
- + save_index_class() : loaded_(false) {}
- +private:
- + config& data(const std::string& name) {
- + std::string save= name;
- + /*
- + * All saves are .gz files now so make sure we use that name when opening
- + * a file. If not some parts of the code use the name with and some parts
- + * without the .gz suffix.
- + */
- + if(save.length() < 3 || save.substr(save.length() - 3) != ".gz") {
- + save += ".gz";
- + }
- +
- + config& cfg = data();
- + if (config &sv = cfg.find_child("save", "save", save)) {
- + return sv;
- + }
- +
- + config &res = cfg.add_child("save");
- + res["save"] = save;
- + return res;
- + }
- + config& data() {
- + if(loaded_ == false) {
- + try {
- + const std::string &filename = get_save_index_file();
- + scoped_istream stream = istream_file(filename);
- + if(is_gzip_file(filename)) {
- + try {
- + read_gz(data_, *stream);
- + } catch (boost::iostreams::gzip_error&) {
- + read(data_, *stream);
- + }
- + } else {
- + read(data_, *stream);
- + }
- + } catch(io_exception& e) {
- + ERR_SAVE << "error reading save index: '" << e.what() << "'\n";
- + } catch(config::error&) {
- + ERR_SAVE << "error parsing save index config file\n";
- + data_.clear();
- + }
- +
- + loaded_ = true;
- + }
- +
- + return data_;
- + }
- +private:
- + bool loaded_;
- + config data_;
- + std::map< std::string, time_t > modified_;
- +} save_index_manager;
- +
- +class filename_filter {
- +public:
- + filename_filter(const std::string& filter) : filter_(filter) {
- + }
- + bool operator()(const std::string& filename) const {
- + return filename.end() == std::search(filename.begin(), filename.end(),
- + filter_.begin(), filter_.end());
- + }
- +private:
- + std::string filter_;
- +};
- +
- +class create_save_info {
- +public:
- + create_save_info(const std::string* d= NULL) : dir(d ? *d : get_saves_dir()) {
- + }
- + save_info operator()(const std::string& filename) const {
- + std::string name= filename;
- + replace_underbar2space(name);
- + time_t modified= file_create_time(dir + "/" + filename);
- + save_index_manager.set_modified(name, modified);
- + return save_info(name, modified);
- + }
- + const std::string dir;
- +};
- +
- +/** Get a list of available saves. */
- +std::vector<save_info> get_saves_list(const std::string* dir, const std::string* filter)
- +{
- + create_save_info creator(dir);
- +
- + std::vector<std::string> filenames;
- + get_files_in_dir(creator.dir,&filenames);
- +
- + if (filter) {
- + filenames.erase(std::remove_if(filenames.begin(), filenames.end(),
- + filename_filter(*filter)));
- + }
- +
- + std::vector<save_info> result;
- + std::transform(filenames.begin(), filenames.end(),
- + std::back_inserter(result), creator);
- + return result;
- +}
- +
- +save_info::save_info(const std::string& n, const time_t& m) : name_(n), modified_(m) {
- +}
- +
- +const std::string& save_info::name() const {
- + return name_;
- +}
- +
- +const time_t& save_info::modified() const {
- + return modified_;
- +}
- +
- +const config& save_info::summary() const {
- + return save_index_manager.get(name());
- +}
- +
- const std::string save_info::format_time_local() const{
- char time_buf[256] = {0};
- - tm* tm_l = localtime(&time_modified);
- + tm* tm_l = localtime(&modified());
- if (tm_l) {
- const size_t res = strftime(time_buf,sizeof(time_buf),
- (preferences::use_twelve_hour_clock_format() ? _("%a %b %d %I:%M %p %Y") : _("%a %b %d %H:%M %Y")),
- @@ -143,7 +315,7 @@ const std::string save_info::format_time_local() const{
- time_buf[0] = 0;
- }
- } else {
- - LOG_SAVE << "localtime() returned null for time " << time_modified << ", save " << name;
- + LOG_SAVE << "localtime() returned null for time " << this->modified() << ", save " << name();
- }
- return time_buf;
- @@ -151,7 +323,7 @@ const std::string save_info::format_time_local() const{
- const std::string save_info::format_time_summary() const
- {
- - time_t t = time_modified;
- + time_t t = modified();
- time_t curtime = time(NULL);
- const struct tm* timeptr = localtime(&curtime);
- if(timeptr == NULL) {
- @@ -205,32 +377,26 @@ const std::string save_info::format_time_summary() const
- return buf;
- }
- -/**
- - * A structure for comparing to save_info objects based on their modified time.
- - * If the times are equal, will order based on the name.
- - */
- -struct save_info_less_time {
- - bool operator()(const save_info& a, const save_info& b) const {
- - if (a.time_modified > b.time_modified) {
- - return true;
- - } else if (a.time_modified < b.time_modified) {
- - return false;
- +bool save_info_less_time::operator() (const save_info& a, const save_info& b) const {
- + if (a.modified() > b.modified()) {
- + return true;
- + } else if (a.modified() < b.modified()) {
- + return false;
- // Special funky case; for files created in the same second,
- // a replay file sorts less than a non-replay file. Prevents
- // a timing-dependent bug where it may look like, at the end
- // of a scenario, the replay and the autosave for the next
- // scenario are displayed in the wrong order.
- - } else if (a.name.find(_(" replay"))==std::string::npos && b.name.find(_(" replay"))!=std::string::npos) {
- - return true;
- - } else if (a.name.find(_(" replay"))!=std::string::npos && b.name.find(_(" replay"))==std::string::npos) {
- - return false;
- - } else {
- - return a.name > b.name;
- - }
- + } else if (a.name().find(_(" replay"))==std::string::npos && b.name().find(_(" replay"))!=std::string::npos) {
- + return true;
- + } else if (a.name().find(_(" replay"))!=std::string::npos && b.name().find(_(" replay"))==std::string::npos) {
- + return false;
- + } else {
- + return a.name() > b.name();
- }
- -};
- +}
- -void manager::read_save_file(const std::string& name, config& cfg, std::string* error_log)
- +void read_save_file(const std::string& name, config& cfg, std::string* error_log)
- {
- std::string modified_name = name;
- replace_space2underbar(modified_name);
- @@ -272,16 +438,7 @@ void manager::read_save_file(const std::string& name, config& cfg, std::string*
- }
- }
- -void manager::load_summary(const std::string& name, config& cfg_summary, std::string* error_log){
- - log_scope("load_game_summary");
- -
- - config cfg;
- - read_save_file(name,cfg,error_log);
- -
- - ::extract_summary_from_config(cfg, cfg_summary);
- -}
- -
- -bool manager::save_game_exists(const std::string& name, const bool compress_saves)
- +bool save_game_exists(const std::string& name, const bool compress_saves)
- {
- std::string fname = name;
- replace_space2underbar(fname);
- @@ -293,61 +450,36 @@ bool manager::save_game_exists(const std::string& name, const bool compress_save
- return file_exists(get_saves_dir() + "/" + fname);
- }
- -std::vector<save_info> manager::get_saves_list(const std::string *dir, const std::string* filter)
- -{
- - // Don't use a reference, it seems to break on arklinux with GCC-4.3.
- - const std::string saves_dir = (dir) ? *dir : get_saves_dir();
- -
- - std::vector<std::string> saves;
- - get_files_in_dir(saves_dir,&saves);
- -
- - std::vector<save_info> res;
- - for(std::vector<std::string>::iterator i = saves.begin(); i != saves.end(); ++i) {
- - if(filter && std::search(i->begin(), i->end(), filter->begin(), filter->end()) == i->end()) {
- - continue;
- - }
- -
- - const time_t modified = file_create_time(saves_dir + "/" + *i);
- -
- - replace_underbar2space(*i);
- - res.push_back(save_info(*i,modified));
- - }
- -
- - std::sort(res.begin(),res.end(),save_info_less_time());
- -
- - return res;
- -}
- -
- -void manager::clean_saves(const std::string &label)
- +void clean_saves(const std::string &label)
- {
- std::vector<save_info> games = get_saves_list();
- std::string prefix = label + "-" + _("Auto-Save");
- std::cerr << "Cleaning saves with prefix '" << prefix << "'\n";
- for (std::vector<save_info>::iterator i = games.begin(); i != games.end(); ++i) {
- - if (i->name.compare(0, prefix.length(), prefix) == 0) {
- - std::cerr << "Deleting savegame '" << i->name << "'\n";
- - delete_game(i->name);
- + if (i->name().compare(0, prefix.length(), prefix) == 0) {
- + std::cerr << "Deleting savegame '" << i->name() << "'\n";
- + delete_game(i->name());
- }
- }
- }
- -void manager::remove_old_auto_saves(const int autosavemax, const int infinite_auto_saves)
- +void remove_old_auto_saves(const int autosavemax, const int infinite_auto_saves)
- {
- const std::string auto_save = _("Auto-Save");
- int countdown = autosavemax;
- if (countdown == infinite_auto_saves)
- return;
- - std::vector<save_info> games = get_saves_list(NULL, &auto_save);
- + std::vector<save_info> games = get_saves_list(&auto_save);
- for (std::vector<save_info>::iterator i = games.begin(); i != games.end(); ++i) {
- if (countdown-- <= 0) {
- - LOG_SAVE << "Deleting savegame '" << i->name << "'\n";
- - delete_game(i->name);
- + LOG_SAVE << "Deleting savegame '" << i->name() << "'\n";
- + delete_game(i->name());
- }
- }
- }
- -void manager::delete_game(const std::string& name)
- +void delete_game(const std::string& name)
- {
- std::string modified_name = name;
- replace_space2underbar(modified_name);
- @@ -356,72 +488,6 @@ void manager::delete_game(const std::string& name)
- remove((get_saves_dir() + "/" + modified_name).c_str());
- }
- -bool save_index::save_index_loaded = false;
- -config save_index::save_index_cfg;
- -
- -config& save_index::load()
- -{
- - if(save_index_loaded == false) {
- - try {
- - const std::string &filename = get_save_index_file();
- - scoped_istream stream = istream_file(filename);
- - if(is_gzip_file(filename)) {
- - try {
- - read_gz(save_index_cfg, *stream);
- - } catch (boost::iostreams::gzip_error&) {
- - read(save_index_cfg, *stream);
- - }
- - } else {
- - read(save_index_cfg, *stream);
- - }
- - } catch(io_exception& e) {
- - ERR_SAVE << "error reading save index: '" << e.what() << "'\n";
- - } catch(config::error&) {
- - ERR_SAVE << "error parsing save index config file\n";
- - save_index_cfg.clear();
- - }
- -
- - save_index_loaded = true;
- - }
- -
- - return save_index_cfg;
- -}
- -
- -config& save_index::save_summary(std::string save)
- -{
- - /*
- - * All saves are .gz files now so make sure we use that name when opening
- - * a file. If not some parts of the code use the name with and some parts
- - * without the .gz suffix.
- - */
- - if(save.length() < 3 || save.substr(save.length() - 3) != ".gz") {
- - save += ".gz";
- - }
- -
- - config& cfg = load();
- - if (config &sv = cfg.find_child("save", "save", save))
- - return sv;
- -
- - config &res = cfg.add_child("save");
- - res["save"] = save;
- - return res;
- -}
- -
- -void save_index::write_save_index()
- -{
- - log_scope("write_save_index()");
- - try {
- - scoped_ostream stream = ostream_file(get_save_index_file());
- - if (preferences::compress_saves()) {
- - write_gz(*stream, load());
- - } else {
- - write(*stream, load());
- - }
- - } catch(io_exception& e) {
- - ERR_SAVE << "error writing to save index file: '" << e.what() << "'\n";
- - }
- -}
- -
- loadgame::loadgame(display& gui, const config& game_config, game_state& gamestate)
- : game_config_(game_config)
- , gui_(gui)
- @@ -443,18 +509,12 @@ void loadgame::show_dialog(bool show_replay, bool cancel_orders)
- if (load_dialog.get_retval() == gui2::twindow::OK){
- if (load_dialog.reselect_difficulty()) {
- + create_save_info creator;
- + save_info info= creator(load_dialog.filename());
- + const config& summary= info.summary();
- - config cfg_summary;
- - std::string dummy;
- -
- - try {
- - manager::load_summary(load_dialog.filename(), cfg_summary, &dummy);
- - } catch(game::load_game_failed&) {
- - cfg_summary["corrupt"] = "yes";
- - }
- -
- - const std::string difficulty_descriptions = cfg_summary["campaign_difficulty_descriptions"];
- - const std::string difficulties = cfg_summary["campaign_difficulties"];
- + const std::string difficulty_descriptions = summary["campaign_difficulty_descriptions"];
- + const std::string difficulties = summary["campaign_difficulties"];
- std::vector<std::string> difficulty_options = utils::split(difficulty_descriptions, ';');
- std::vector<std::string> difficulty_list = utils::split(difficulties, ',');
- @@ -511,7 +571,7 @@ void loadgame::load_game(
- throw load_game_cancelled_exception();
- std::string error_log;
- - manager::read_save_file(filename_, load_config_, &error_log);
- + read_save_file(filename_, load_config_, &error_log);
- if(!error_log.empty()) {
- try {
- @@ -610,7 +670,7 @@ void loadgame::load_multiplayer_game()
- cursor::setter cur(cursor::WAIT);
- log_scope("load_game");
- - manager::read_save_file(filename_, load_config_, &error_log);
- + read_save_file(filename_, load_config_, &error_log);
- copy_era(load_config_);
- gamestate_ = game_state(load_config_);
- @@ -773,7 +833,7 @@ int savegame::show_save_dialog(CVideo& video, const std::string& message, const
- bool savegame::check_overwrite(CVideo& video)
- {
- std::string filename = filename_;
- - if (manager::save_game_exists(filename, compress_saves_)) {
- + if (save_game_exists(filename, compress_saves_)) {
- std::stringstream message;
- message << _("Save already exists. Do you want to overwrite it?") << "\n" << _("Name: ") << filename;
- int retval = gui2::show_message(video, _("Overwrite?"), message.str(), gui2::tmessage::yes_no_buttons);
- @@ -905,20 +965,11 @@ void savegame::write_game(config_writer &out) const
- void savegame::finish_save_game(const config_writer &out)
- {
- - std::string name = gamestate_.classification().label;
- - replace_space2underbar(name);
- - std::string fname(get_saves_dir() + "/" + name);
- -
- try {
- if(!out.good()) {
- throw game::save_game_failed(_("Could not write to file"));
- }
- -
- - config& summary = save_index::save_summary(gamestate_.classification().label);
- - extract_summary_data_from_save(summary);
- - const int mod_time = static_cast<int>(file_create_time(fname));
- - summary["mod_time"] = str_cast(mod_time);
- - save_index::write_save_index();
- + save_index_manager.rebuild(gamestate_.classification().label);
- } catch(io_exception& e) {
- throw game::save_game_failed(e.what());
- }
- @@ -937,75 +988,6 @@ scoped_ostream savegame::open_save_game(const std::string &label)
- }
- }
- -void savegame::extract_summary_data_from_save(config& out)
- -{
- - const bool has_replay = gamestate_.replay_data.empty() == false;
- - bool has_snapshot(gamestate_.snapshot.child("side"));
- -
- - out["replay"] = has_replay;
- - out["snapshot"] = has_snapshot;
- -
- - out["label"] = gamestate_.classification().label;
- - out["parent"] = gamestate_.classification().parent;
- - out["campaign"] = gamestate_.classification().campaign;
- - out["campaign_type"] = gamestate_.classification().campaign_type;
- - out["campaign_difficulties"] = utils::join<std::vector<std::string> >(gamestate_.classification().campaign_difficulties, ",");
- - out["campaign_difficulty_descriptions"] = utils::join<std::vector<std::string> >
- - (gamestate_.classification().campaign_difficulty_descriptions, ";");
- - out["scenario"] = gamestate_.classification().scenario;
- - out["difficulty"] = gamestate_.classification().difficulty;
- - out["version"] = gamestate_.classification().version;
- - out["corrupt"] = "";
- -
- - if(has_snapshot) {
- - out["turn"] = gamestate_.snapshot["turn_at"];
- - if(gamestate_.snapshot["turns"] != "-1") {
- - out["turn"] = out["turn"].str() + "/" + gamestate_.snapshot["turns"].str();
- - }
- - }
- -
- - // Find the first human leader so we can display their icon in the load menu.
- -
- - /** @todo Ideally we should grab all leaders if there's more than 1 human player? */
- - std::string leader;
- -
- - bool shrouded = false;
- -
- - const config& snapshot = has_snapshot ? gamestate_.snapshot : gamestate_.starting_pos;
- - foreach (const config &side, snapshot.child_range("side"))
- - {
- - if (side["controller"] != "human") {
- - continue;
- - }
- - if (side["shroud"].to_bool()) {
- - shrouded = true;
- - }
- -
- - foreach (const config &u, side.child_range("unit"))
- - {
- - if (u["canrecruit"].to_bool()) {
- - leader = u["id"].str();
- - break;
- - }
- - }
- - }
- -
- - out["leader"] = leader;
- - out["map_data"] = "";
- -
- - if(!shrouded) {
- - if(has_snapshot) {
- - if (!gamestate_.snapshot.find_child("side", "shroud", "yes")) {
- - out["map_data"] = gamestate_.snapshot["map_data"];
- - }
- - } else if(has_replay) {
- - if (!gamestate_.starting_pos.find_child("side", "shroud", "yes")) {
- - out["map_data"] = gamestate_.starting_pos["map_data"];
- - }
- - }
- - }
- -}
- -
- scenariostart_savegame::scenariostart_savegame(game_state &gamestate, const bool compress_saves)
- : savegame(gamestate, compress_saves)
- {
- @@ -1055,7 +1037,7 @@ void autosave_savegame::autosave(const bool disable_autosave, const int autosave
- save_game_automatic(gui_.video());
- - manager::remove_old_auto_saves(autosave_max, infinite_autosaves);
- + remove_old_auto_saves(autosave_max, infinite_autosaves);
- }
- void autosave_savegame::create_filename()
- diff --git a/src/savegame.hpp b/src/savegame.hpp
- index 784939b..3d8d5d5 100644
- --- a/src/savegame.hpp
- +++ b/src/savegame.hpp
- @@ -31,66 +31,47 @@ struct illegal_filename_exception {};
- namespace savegame {
- /** Filename and modification date for a file list */
- -struct save_info {
- - save_info(const std::string& n, time_t t) : name(n), time_modified(t) {}
- - std::string name;
- - time_t time_modified;
- -
- +class save_info {
- +private:
- + friend class create_save_info;
- +private:
- + save_info(const std::string& name, const time_t& modified);
- +public:
- + const std::string& name() const;
- + const time_t& modified() const;
- +public:
- const std::string format_time_summary() const;
- const std::string format_time_local() const;
- + const config& summary() const;
- +private:
- + std::string name_;
- + time_t modified_;
- };
- /**
- -Container for a couple of savefile manipulating methods.
- -Note: You are not supposed to instantiate this class.
- -*/
- -class manager
- -{
- -public:
- - /** Read summary information out of an existing savefile. */
- - static void load_summary(const std::string& name, config& cfg_summary, std::string* error_log);
- - /** Read the complete config information out of a savefile. */
- - static void read_save_file(const std::string& name, config& cfg, std::string* error_log);
- -
- - /** Returns true if there is already a savegame with that name. */
- - static bool save_game_exists(const std::string& name, const bool compress_saves);
- - /** Get a list of available saves. */
- - static std::vector<save_info> get_saves_list(const std::string *dir = NULL, const std::string* filter = NULL);
- -
- - /** Delete all autosaves of a certain scenario. */
- - static void clean_saves(const std::string &label);
- - /** Remove autosaves that are no longer needed (according to the autosave policy in the preferences). */
- - static void remove_old_auto_saves(const int autosavemax, const int infinite_auto_saves);
- - /** Delete a savegame. */
- - static void delete_game(const std::string& name);
- -
- -private:
- - /** Default-Constructor (don't instantiate this class) */
- - manager() {}
- + * A structure for comparing to save_info objects based on their modified time.
- + * If the times are equal, will order based on the name.
- + */
- +struct save_info_less_time {
- + bool operator()(const save_info& a, const save_info& b) const;
- };
- -/**
- -Container for methods dealing with the save_index file.
- -Note: You are not supposed to instantiate this class.
- -*/
- -class save_index
- -{
- -public:
- - /** Determines/Adds the "save"-child of the summary config. */
- - static config& save_summary(std::string save);
- - /** Update the save_index file with changed savegame information. */
- - static void write_save_index();
- +std::vector<save_info> get_saves_list(const std::string* dir= NULL, const std::string* filter = NULL);
- -private:
- - /** Default-Constructor (don't instantiate this class) */
- - save_index() {}
- +/** Read the complete config information out of a savefile. */
- +void read_save_file(const std::string& name, config& cfg, std::string* error_log);
- - /** Read the complete config information out of the save_index file. */
- - static config& load();
- +/** Returns true if there is already a savegame with that name. */
- +bool save_game_exists(const std::string& name, const bool compress_saves);
- - static bool save_index_loaded; /** Tells, if the save_index config has been already loaded. */
- - static config save_index_cfg; /** save_index config (who would have guessed that ;-). */
- -};
- +/** Delete all autosaves of a certain scenario. */
- +void clean_saves(const std::string &label);
- +
- +/** Remove autosaves that are no longer needed (according to the autosave policy in the preferences). */
- +void remove_old_auto_saves(const int autosavemax, const int infinite_auto_saves);
- +
- +/** Delete a savegame. */
- +void delete_game(const std::string& name);
- /** The class for loading a savefile. */
- class loadgame
- @@ -212,8 +193,7 @@ private:
- void finish_save_game(const config_writer &out);
- /** Throws game::save_game_failed. */
- scoped_ostream open_save_game(const std::string &label);
- - /** Read the summary data from a savegame to display this information in the load-game dialog. */
- - void extract_summary_data_from_save(config& out);
- + friend class save_info;
- game_state& gamestate_;
Advertisement
Add Comment
Please, Sign In to add comment