Push config_writer furthur up auto-save callchain.

Doesn't make any difference yet, but eventually we should be creating
config_writer at top level and passing it around for each subsystem to
write to it, instead of pasting together a config from each subsystem
then writing the whole thing out.
This commit is contained in:
Rusty Russell 2006-06-18 05:27:27 +00:00
parent cc3a8f16fb
commit 50b7429d0f
8 changed files with 149 additions and 18 deletions

View file

@ -360,6 +360,33 @@ void write_player(const player_info& player, config& cfg)
cfg["can_recruit"] = can_recruit_str;
}
void write_player(config_writer &out, const player_info& player)
{
char buf[50];
snprintf(buf,sizeof(buf),"%d",player.gold);
out.write_key_val("gold", buf);
for(std::vector<unit>::const_iterator i = player.available_units.begin();
i != player.available_units.end(); ++i) {
config new_cfg;
i->write(new_cfg);
out.write_child("unit",new_cfg);
}
std::stringstream can_recruit;
std::copy(player.can_recruit.begin(),player.can_recruit.end(),std::ostream_iterator<std::string>(can_recruit,","));
std::string can_recruit_str = can_recruit.str();
//remove the trailing comma
if(can_recruit_str.empty() == false) {
can_recruit_str.resize(can_recruit_str.size()-1);
}
out.write_key_val("can_recruit", can_recruit_str);
}
// Deprecated, use other write_game below.
void write_game(const game_state& game, config& cfg/*, WRITE_GAME_MODE mode*/)
{
@ -413,10 +440,10 @@ void write_game(config_writer &out, const game_state& game)
for(std::map<std::string, player_info>::const_iterator i=game.players.begin();
i!=game.players.end(); ++i) {
config new_cfg;
write_player(i->second, new_cfg);
new_cfg["save_id"]=i->first;
out.write_child("player", new_cfg);
out.open_child("player");
out.write_key_val("save_id", i->first);
write_player(out, i->second);
out.close_child("player");
}
if(game.replay_data.child("replay") == NULL) {
@ -425,7 +452,9 @@ void write_game(config_writer &out, const game_state& game)
out.write_child("snapshot",game.snapshot);
out.write_child("replay_start",game.starting_pos);
out.write_child("statistics",statistics::write_stats());
out.open_child("statistics");
statistics::write_stats(out);
out.close_child("statistics");
}
//a structure for comparing to save_info objects based on their modified time.
@ -540,14 +569,10 @@ void finish_save_game(config_writer &out, const game_state& state, const std::st
//throws game::save_game_failed
void save_game(const game_state& state)
{
try {
scoped_ostream os(open_save_game(state.label));
config_writer out(*os, preferences::compress_saves(), PACKAGE);
write_game(out, state);
finish_save_game(out, state, state.label);
} catch(io_exception& e) {
throw game::save_game_failed(e.what());
}
scoped_ostream os(open_save_game(state.label));
config_writer out(*os, preferences::compress_saves(), PACKAGE);
write_game(out, state);
finish_save_game(out, state, state.label);
}
namespace {

View file

@ -164,13 +164,14 @@ void read_save_file(const std::string& name, config& cfg, std::string* error_log
game_state read_game(const game_data& data, const config* cfg);
void write_game(const game_state& game, config& cfg/*, WRITE_GAME_MODE mode=WRITE_FULL_GAME*/);
void write_game(config_writer &out, const game_state& game);
// function returns true iff there is already savegame with that name
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(scoped_ostream &ostream, const game_state& state, const std::string &label);
void finish_save_game(config_writer &out, const game_state& state, const std::string &label);
//functions to load/save games.
void load_game(const game_data& data, const std::string& name, game_state& state, std::string* error_log);

View file

@ -30,6 +30,8 @@
#include "wassert.hpp"
#include "wml_separators.hpp"
#include "wesconfig.h"
#include <sys/time.h>
#include <time.h>
#include <sstream>
@ -465,7 +467,10 @@ namespace events{
void menu_handler::autosave(const std::string &label, unsigned turn, const config &starting_pos) const
{
struct timeval start, end;
gettimeofday(&start, NULL);
config snapshot;
write_game_snapshot(snapshot);
try {
if (label.empty()) {
@ -477,6 +482,10 @@ namespace events{
gui::show_dialog(*gui_,NULL,"",_("Could not auto save the game. Please save the game manually."),gui::MESSAGE);
//do not bother retrying, since the user can just save the game
}
gettimeofday(&end, NULL);
unsigned long long s = start.tv_sec * 1000000ULL + start.tv_usec;
unsigned long long e = end.tv_sec * 1000000ULL + end.tv_usec;
std::cerr << "Microseconds to save: " << (unsigned long)(e - s) << "\n";
}
void menu_handler::load_game(){

View file

@ -30,6 +30,8 @@
#include "unit_display.hpp"
#include "util.hpp"
#include "wassert.hpp"
#include "wesconfig.h"
#include "serialization/binary_or_text.hpp"
#include <cstdio>
#include <cstdlib>
@ -222,7 +224,10 @@ void replay::save_game(const std::string& label, const config& snapshot,
saveInfo_.label = label;
::save_game(saveInfo_);
scoped_ostream os(open_save_game(label));
config_writer out(*os, preferences::compress_saves(), PACKAGE);
::write_game(out, saveInfo_);
finish_save_game(out, saveInfo_, saveInfo_.label);
saveInfo_.replay_data = config();
saveInfo_.snapshot = config();

View file

@ -45,9 +45,6 @@ public:
void save_game(const std::string& label, const config& snapshot,
const config& starting_pos, bool include_replay = true);
void write_game(config_writer &out, const std::string& label, const config& snapshot,
const config& starting_pos, bool include_replay);
void add_start();
void add_recruit(int unit_index, const gamemap::location& loc);
void add_recall(int unit_index, const gamemap::location& loc);

View file

@ -16,6 +16,7 @@
#include "statistics.hpp"
#include "util.hpp"
#include "log.hpp"
#include "serialization/binary_or_text.hpp"
#define ERR_NG lg::err(lg::engine)
@ -37,6 +38,7 @@ struct scenario_stats
explicit scenario_stats(const config& cfg);
config write() const;
void write(config_writer &out) const;
std::vector<stats> team_stats;
std::string scenario_name;
@ -62,6 +64,16 @@ config scenario_stats::write() const
return res;
}
void scenario_stats::write(config_writer &out) const
{
out.write_key_val("scenario", scenario_name);
for(std::vector<stats>::const_iterator i = team_stats.begin(); i != team_stats.end(); ++i) {
out.open_child("team");
i->write(out);
out.close_child("team");
}
}
std::vector<scenario_stats> master_stats;
stats& get_stats(int team)
@ -91,6 +103,15 @@ config write_str_int_map(const stats::str_int_map& m)
return res;
}
void write_str_int_map(config_writer &out, const stats::str_int_map& m)
{
for(stats::str_int_map::const_iterator i = m.begin(); i != m.end(); ++i) {
char buf[50];
snprintf(buf,sizeof(buf),"%d",i->second);
out.write_key_val(i->first, buf);
}
}
stats::str_int_map read_str_int_map(const config& cfg)
{
stats::str_int_map m;
@ -116,6 +137,19 @@ config write_battle_result_map(const stats::battle_result_map& m)
return res;
}
void write_battle_result_map(config_writer &out, const stats::battle_result_map& m)
{
for(stats::battle_result_map::const_iterator i = m.begin(); i != m.end(); ++i) {
out.open_child("sequence");
write_str_int_map(out, i->second);
char buf[50];
snprintf(buf,sizeof(buf),"%d",i->first);
out.write_key_val("_num", buf);
out.close_child("sequence");
}
}
stats::battle_result_map read_battle_result_map(const config& cfg)
{
stats::battle_result_map m;
@ -209,6 +243,50 @@ config stats::write() const
return res;
}
void stats::write(config_writer &out) const
{
out.open_child("recruits");
write_str_int_map(out, recruits);
out.close_child("recruits");
out.open_child("recalls");
write_str_int_map(out, recalls);
out.close_child("recalls");
out.open_child("advances");
write_str_int_map(out, advanced_to);
out.close_child("advances");
out.open_child("deaths");
write_str_int_map(out, deaths);
out.close_child("deaths");
out.open_child("killed");
write_str_int_map(out, killed);
out.close_child("killed");
out.open_child("attacks");
write_battle_result_map(out, attacks);
out.close_child("attacks");
out.open_child("defends");
write_battle_result_map(out, defends);
out.close_child("defends");
char buf[50];
snprintf(buf,sizeof(buf),"%d",recruit_cost);
out.write_key_val("recruit_cost", buf);
snprintf(buf,sizeof(buf),"%d",recall_cost);
out.write_key_val("recall_cost", buf);
snprintf(buf,sizeof(buf),"%d",damage_inflicted);
out.write_key_val("damage_inflicted", buf);
snprintf(buf,sizeof(buf),"%d",damage_taken);
out.write_key_val("damage_taken", buf);
snprintf(buf,sizeof(buf),"%d",expected_damage_inflicted);
out.write_key_val("expected_damage_inflicted", buf);
snprintf(buf,sizeof(buf),"%d",expected_damage_taken);
out.write_key_val("expected_damage_taken", buf);
}
void stats::read(const config& cfg)
{
if(cfg.child("recruits")) {
@ -430,6 +508,17 @@ config write_stats()
return res;
}
void write_stats(config_writer &out)
{
out.write_key_val("mid_scenario", mid_scenario ? "true" : "false");
for(std::vector<scenario_stats>::const_iterator i = master_stats.begin(); i != master_stats.end(); ++i) {
out.open_child("scenario");
i->write(out);
out.close_child("scenario");
}
}
void read_stats(const config& cfg)
{
fresh_stats();

View file

@ -14,6 +14,7 @@
#ifndef STATISTICS_HPP_INCLUDED
#define STATISTICS_HPP_INCLUDED
class config_writer;
class unit;
#include "actions.hpp"
@ -25,6 +26,7 @@ namespace statistics
explicit stats(const config& cfg);
config write() const;
void write(config_writer &out) const;
void read(const config& cfg);
typedef std::map<std::string,int> str_int_map;
@ -94,6 +96,7 @@ namespace statistics
void advance_unit(const unit& u);
config write_stats();
void write_stats(config_writer &out);
void read_stats(const config& cfg);
void fresh_stats();
void clear_current_scenario();

View file

@ -24,6 +24,7 @@
class unit;
class display;
class gamestatus;
class config_writer;
#include <set>
#include <string>
@ -145,6 +146,7 @@ class unit
*/
void read(const config& cfg);
void write(config& cfg) const;
void write(config_writer& out) const;
void assign_role(const std::string& role);
const std::vector<attack_type>& attacks() const;