Auto-save the current game regularly, to reduce the loss in case of crash

This commit is contained in:
Olivier Teulière 2012-04-12 21:46:53 +02:00
parent 6391dd34e1
commit de5783d51a
4 changed files with 91 additions and 53 deletions

View file

@ -64,66 +64,65 @@ void Settings::Destroy()
}
namespace
string Settings::GetConfigFileDir()
{
string getConfigFileName()
{
string fileName;
string fileName;
#ifdef WIN32
char szPath[MAX_PATH];
// Get the AppData directory
if (SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
NULL, 0, szPath) == S_OK)
{
fileName = szPath + string("\\eliot");
char szPath[MAX_PATH];
// Get the AppData directory
if (SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
NULL, 0, szPath) == S_OK)
{
fileName = szPath + string("\\eliot");
#if 1
strncpy(szPath, fileName.c_str(), MAX_PATH);
// Try to create the directory
// We don't care about the results
CreateDirectory(fileName.c_str(), NULL);
strncpy(szPath, fileName.c_str(), MAX_PATH);
// Try to create the directory
// We don't care about the results
CreateDirectory(fileName.c_str(), NULL);
#endif
}
if (fileName != "")
fileName += "\\";
fileName += "eliot.cfg";
}
if (fileName != "")
fileName += "\\";
#else
// Follow the XDG Base Directory Specification (from freedesktop.org)
// XXX: In fact we don't follow it to the letter, because the location
// of the config file could be different when reading and writing.
// But in the case of Eliot it's not very important (we don't try to
// merge config files)...
const char *configDir = getenv("XDG_CONFIG_HOME");
if (configDir != NULL)
fileName = configDir;
else
{
// Fallback to the default value: $HOME/.config
configDir = getenv("HOME");
if (configDir)
fileName = configDir + string("/.config");
}
fileName += "/eliot";
// Follow the XDG Base Directory Specification (from freedesktop.org)
// XXX: In fact we don't follow it to the letter, because the location
// of the config file could be different when reading and writing.
// But in the case of Eliot it's not very important (we don't try to
// merge config files)...
const char *configDir = getenv("XDG_CONFIG_HOME");
if (configDir != NULL)
fileName = configDir;
else
{
// Fallback to the default value: $HOME/.config
configDir = getenv("HOME");
if (configDir)
fileName = configDir + string("/.config");
}
fileName += "/eliot";
#if defined(HAVE_SYS_STAT_H) && defined(HAVE_SYS_TYPES_H)
// Create the directory if it doesn't exist
struct stat sb;
if (fileName != "" && stat(fileName.c_str(), &sb) == -1)
// Create the directory if it doesn't exist
struct stat sb;
if (fileName != "" && stat(fileName.c_str(), &sb) == -1)
{
// Try to create the directory with mode 0700
if (mkdir(fileName.c_str(), S_IRWXU))
{
// Try to create the directory with mode 0700
if (mkdir(fileName.c_str(), S_IRWXU))
{
// The directory could not be created. Too bad...
// Saving the configuration file will definitely fail.
}
// The directory could not be created. Too bad...
// Saving the configuration file will definitely fail.
}
#endif
fileName += "/eliot.cfg";
#endif
return fileName;
}
#endif
fileName += "/";
#endif
return fileName;
}
namespace
{
#ifdef HAVE_LIBCONFIG
template<typename T>
void copySetting(const Config &srcConf, Config &dstConf, const char *path)
@ -142,7 +141,7 @@ namespace
Settings::Settings()
{
#ifdef HAVE_LIBCONFIG
m_fileName = ::getConfigFileName();
m_fileName = GetConfigFileDir() + "eliot.cfg";
m_conf = new Config;
// ============== General options ==============

View file

@ -53,6 +53,9 @@ public:
/// Destroy the singleton cleanly
static void Destroy();
/// Return the config file directory, with a '/' (or '\') appended to it
static string GetConfigFileDir();
~Settings();
/// Save the current value of the settings to a configuration file

View file

@ -46,6 +46,9 @@
#include "turn.h"
#include "move.h"
#include "debug.h"
#include "round.h"
#include "settings.h"
#include "new_game.h"
#include "tables_dialog.h"
#include "prefs_dialog.h"
@ -64,9 +67,6 @@
#include "aux_window.h"
#include "qtcommon.h"
#include "round.h"
#include "coord.h"
INIT_LOGGER(qt, MainWindow);
@ -87,6 +87,9 @@ MainWindow::MainWindow(QWidget *iParent)
QtCommon::CheckConversions();
#endif
// Path to the auto-saved game
m_autoSaveGame = Settings::GetConfigFileDir() + "autosave.xml";
LOG_DEBUG("Creating main window");
m_ui.setupUi(this);
createMenu();
@ -258,6 +261,10 @@ void MainWindow::refresh()
m_currentTurn = currTurn;
emit turnChanged(currTurn, isLastTurn);
}
// Update the auto-saved game
m_game->save(m_autoSaveGame);
#ifdef DEBUG
m_game->printTurns();
#endif
@ -610,6 +617,9 @@ void MainWindow::createMenu()
menuFile->addSeparator();
addMenuAction(menuFile, _q("&Load..."), _q("Ctrl+O"),
_q("Load an existing game"), SLOT(onGameLoad()));
addMenuAction(menuFile, _q("Load the auto-saved game"), QString(""),
_q("Load the automatically saved game (useful after a crash)"),
SLOT(onGameLoadAutoSave()));
m_actionGameSaveAs = addMenuAction(menuFile, _q("&Save as..."), _q("Ctrl+S"),
_q("Save the current game"), SLOT(onGameSaveAs()));
menuFile->addSeparator();
@ -740,6 +750,18 @@ void MainWindow::onGameNew()
void MainWindow::onGameLoad()
{
loadGame("");
}
void MainWindow::onGameLoadAutoSave()
{
loadGame(qfl(m_autoSaveGame));
}
void MainWindow::loadGame(QString fileName)
{
if (m_dic == NULL)
{
@ -754,7 +776,8 @@ void MainWindow::onGameLoad()
return;
}
QString fileName = QFileDialog::getOpenFileName(this, _q("Load a game"));
if (fileName == "")
fileName = QFileDialog::getOpenFileName(this, _q("Load a game"));
if (fileName != "")
{
try

View file

@ -21,6 +21,7 @@
#ifndef MAIN_WINDOW_H_
#define MAIN_WINDOW_H_
#include <string>
#include <QMainWindow>
#include <ui/main_window.ui.h>
@ -28,6 +29,9 @@
#include "coord_model.h"
using std::string;
class Dictionary;
class Bag;
class Board;
@ -71,6 +75,7 @@ protected:
private slots:
void onGameNew();
void onGameLoad();
void onGameLoadAutoSave();
void onGameSaveAs();
void onGamePrint();
void onGameQuit();
@ -152,6 +157,8 @@ private:
static const char * m_windowName;
string m_autoSaveGame;
/// Auxiliary windows
//@{
QAction *m_actionWindowsBag;
@ -205,6 +212,12 @@ private:
*/
void linkArbitrationAnd7P1();
/**
* Load the game saved in the given file. If iFileName is an empty string,
* the auto-saved game will be loaded.
*/
void loadGame(QString iFileName);
};
#endif