Savegame reorganization Step 1: a simpler interface to saving and loading.
Move finish_save_game and extract_summary_data_from_save to savegame.cpp.
This commit is contained in:
parent
a3757e256f
commit
99f4bbd384
4 changed files with 106 additions and 107 deletions
|
@ -116,7 +116,6 @@ static void replace_space2underbar(std::string &name) {
|
|||
#endif /* _WIN32 */
|
||||
|
||||
static void extract_summary_from_config(config& cfg_save, config& cfg_summary);
|
||||
static void extract_summary_data_from_save(const game_state& gamestate, config& out);
|
||||
|
||||
player_info* game_state::get_player(const std::string& id) {
|
||||
std::map< std::string, player_info >::iterator found = players.find(id);
|
||||
|
@ -857,27 +856,6 @@ scoped_ostream open_save_game(const std::string &label)
|
|||
}
|
||||
}
|
||||
|
||||
void finish_save_game(config_writer &out, const game_state& gamestate, const std::string &label)
|
||||
{
|
||||
std::string name = label;
|
||||
std::replace(name.begin(),name.end(),' ','_');
|
||||
std::string fname(get_saves_dir() + "/" + name);
|
||||
|
||||
try {
|
||||
if(!out.good()) {
|
||||
throw game::save_game_failed(_("Could not write to file"));
|
||||
}
|
||||
|
||||
config& summary = save_summary(label);
|
||||
extract_summary_data_from_save(gamestate,summary);
|
||||
const int mod_time = static_cast<int>(file_create_time(fname));
|
||||
summary["mod_time"] = str_cast(mod_time);
|
||||
write_save_index();
|
||||
} catch(io_exception& e) {
|
||||
throw game::save_game_failed(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool save_index_loaded = false;
|
||||
config save_index_cfg;
|
||||
|
@ -933,83 +911,6 @@ void write_save_index()
|
|||
}
|
||||
}
|
||||
|
||||
void extract_summary_data_from_save(const game_state& gamestate, config& out)
|
||||
{
|
||||
const bool has_replay = gamestate.replay_data.empty() == false;
|
||||
const bool has_snapshot = gamestate.snapshot.child("side");
|
||||
|
||||
out["replay"] = has_replay ? "yes" : "no";
|
||||
out["snapshot"] = has_snapshot ? "yes" : "no";
|
||||
|
||||
out["label"] = gamestate.label;
|
||||
out["campaign"] = gamestate.campaign;
|
||||
out["campaign_type"] = gamestate.campaign_type;
|
||||
out["scenario"] = gamestate.scenario;
|
||||
out["difficulty"] = gamestate.difficulty;
|
||||
out["version"] = gamestate.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;
|
||||
|
||||
for(std::map<std::string, player_info>::const_iterator p = gamestate.players.begin();
|
||||
p!=gamestate.players.end(); ++p) {
|
||||
for(std::vector<unit>::const_iterator u = p->second.available_units.begin(); u != p->second.available_units.end(); ++u) {
|
||||
if(u->can_recruit()) {
|
||||
leader = u->type_id();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool shrouded = false;
|
||||
|
||||
if(leader == "") {
|
||||
const config& snapshot = has_snapshot ? gamestate.snapshot : gamestate.starting_pos;
|
||||
foreach (const config &side, snapshot.child_range("side"))
|
||||
{
|
||||
if (side["controller"] != "human") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (utils::string_bool(side["shroud"])) {
|
||||
shrouded = true;
|
||||
}
|
||||
|
||||
foreach (const config &u, side.child_range("unit"))
|
||||
{
|
||||
if (utils::string_bool(u["canrecruit"], false)) {
|
||||
leader = u["id"];
|
||||
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"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void extract_summary_from_config(config& cfg_save, config& cfg_summary)
|
||||
{
|
||||
const config &cfg_snapshot = cfg_save.child("snapshot");
|
||||
|
|
|
@ -327,7 +327,6 @@ bool save_game_exists(const std::string & name);
|
|||
|
||||
/** Throws game::save_game_failed. */
|
||||
scoped_ostream open_save_game(const std::string &label);
|
||||
void finish_save_game(config_writer &out, const game_state& gamestate, const std::string &label);
|
||||
|
||||
/** Load/Save games. */
|
||||
void load_game(const std::string& name, game_state& gamestate, std::string* error_log);
|
||||
|
|
101
src/savegame.cpp
101
src/savegame.cpp
|
@ -16,6 +16,7 @@
|
|||
#include "savegame.hpp"
|
||||
|
||||
#include "dialogs.hpp" //FIXME: move illegal file character function here and get rid of this include
|
||||
#include "foreach.hpp"
|
||||
#include "game_end_exceptions.hpp"
|
||||
#include "game_events.hpp"
|
||||
#include "gettext.hpp"
|
||||
|
@ -145,7 +146,7 @@ void savegame::save_game_internal(const std::string& filename)
|
|||
{
|
||||
config_writer out(ss, preferences::compress_saves());
|
||||
::write_game(out, snapshot_, gamestate_);
|
||||
finish_save_game(out, gamestate_, gamestate_.label);
|
||||
finish_save_game(out);
|
||||
}
|
||||
scoped_ostream os(open_save_game(filename_));
|
||||
(*os) << ss.str();
|
||||
|
@ -155,6 +156,104 @@ void savegame::save_game_internal(const std::string& filename)
|
|||
}
|
||||
}
|
||||
|
||||
void savegame::finish_save_game(config_writer &out)
|
||||
{
|
||||
std::string name = gamestate_.label;
|
||||
std::replace(name.begin(),name.end(),' ','_');
|
||||
std::string fname(get_saves_dir() + "/" + name);
|
||||
|
||||
try {
|
||||
if(!out.good()) {
|
||||
throw game::save_game_failed(_("Could not write to file"));
|
||||
}
|
||||
|
||||
config& summary = save_summary(gamestate_.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);
|
||||
write_save_index();
|
||||
} catch(io_exception& e) {
|
||||
throw game::save_game_failed(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void savegame::extract_summary_data_from_save(config& out)
|
||||
{
|
||||
const bool has_replay = gamestate_.replay_data.empty() == false;
|
||||
const bool has_snapshot = gamestate_.snapshot.child("side");
|
||||
|
||||
out["replay"] = has_replay ? "yes" : "no";
|
||||
out["snapshot"] = has_snapshot ? "yes" : "no";
|
||||
|
||||
out["label"] = gamestate_.label;
|
||||
out["campaign"] = gamestate_.campaign;
|
||||
out["campaign_type"] = gamestate_.campaign_type;
|
||||
out["scenario"] = gamestate_.scenario;
|
||||
out["difficulty"] = gamestate_.difficulty;
|
||||
out["version"] = gamestate_.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;
|
||||
|
||||
for(std::map<std::string, player_info>::const_iterator p = gamestate_.players.begin();
|
||||
p!=gamestate_.players.end(); ++p) {
|
||||
for(std::vector<unit>::const_iterator u = p->second.available_units.begin(); u != p->second.available_units.end(); ++u) {
|
||||
if(u->can_recruit()) {
|
||||
leader = u->type_id();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool shrouded = false;
|
||||
|
||||
if(leader == "") {
|
||||
const config& snapshot = has_snapshot ? gamestate_.snapshot : gamestate_.starting_pos;
|
||||
foreach (const config &side, snapshot.child_range("side"))
|
||||
{
|
||||
if (side["controller"] != "human") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (utils::string_bool(side["shroud"])) {
|
||||
shrouded = true;
|
||||
}
|
||||
|
||||
foreach (const config &u, side.child_range("unit"))
|
||||
{
|
||||
if (utils::string_bool(u["canrecruit"], false)) {
|
||||
leader = u["id"];
|
||||
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"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void savegame::set_filename(std::string filename)
|
||||
{
|
||||
filename.erase(std::remove_if(filename.begin(), filename.end(),
|
||||
|
|
|
@ -100,20 +100,20 @@ private:
|
|||
data manipulation has to happen before calling this method */
|
||||
void save_game_internal(const std::string& filename);
|
||||
|
||||
void finish_save_game(config_writer &out);
|
||||
void extract_summary_data_from_save(config& out);
|
||||
|
||||
game_state& gamestate_;
|
||||
|
||||
/** Gamestate information at the time of saving. Note that this object is needed here, since
|
||||
even if it is empty the code relies on it to be there. */
|
||||
config snapshot_;
|
||||
|
||||
/** Filename of the savegame file on disk */
|
||||
std::string filename_;
|
||||
std::string filename_; /** Filename of the savegame file on disk */
|
||||
|
||||
/** Title of the savegame dialog */
|
||||
const std::string title_;
|
||||
const std::string title_; /** Title of the savegame dialog */
|
||||
|
||||
/** Error message to be displayed if the savefile could not be generated. */
|
||||
std::string error_message_;
|
||||
std::string error_message_; /** Error message to be displayed if the savefile could not be generated. */
|
||||
|
||||
/** Determines if the save is done interactively or not. This controls if a filename is
|
||||
generated automatically (interactive = false) and if a message is displayed that the
|
||||
|
|
Loading…
Add table
Reference in a new issue