1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
#include "highscore.h"
#include "instance.h"
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdexcept>
using std::string;
/*
* HighScores
*/
HighScores * HighScores::singleton_ (0);
HighScores & HighScores::Instance() {
if (!singleton_) {
singleton_ = new HighScores;
InstancesManager::Instance().Push(DestroyInstance);
}
return *singleton_;
}
void HighScores::Update()
{
const std::string score_file_name (Config::Instance().GetScoreFileName());
PosixBuf filebuf (score_file_name, O_RDWR | O_CREAT, 0660);
if (filebuf.FD() < 0)
throw std::runtime_error ("Cannot open high scores file '"+score_file_name+"'!");
if (filebuf.Lock(last_score_ != -1 ? F_WRLCK : F_RDLCK) == -1)
throw std::runtime_error ("Cannot lock high scores file '"+score_file_name+"'!");
std::iostream file (&filebuf);
Load(file);
file.clear();
if (last_score_ != -1) {
high_scores_[last_size_].insert(HighScore(last_score_));
last_score_ = -1;
if (filebuf.Truncate() != 0)
throw std::runtime_error ("Cannot update high scores file '"+score_file_name+"'!");
file.seekg(0);
Save(file);
}
}
const std::multiset<HighScore> * HighScores::Get(Coord window_size) const
{
const Ctn::const_iterator it (high_scores_.find(window_size));
return it == high_scores_.end() ? 0 : &(it->second);
}
void HighScores::Load(std::istream & scores_file)
{
high_scores_.clear();
int score;
Coord window_size;
string name;
std::time_t score_date = 0;
while (scores_file.peek() != EOF) {
if (scores_file.peek() == 'T') {
scores_file.ignore();
if (!(scores_file >> score_date >> score >> window_size.x >> window_size.y && std::getline(scores_file, name))) {
break;
}
}
else {
if (!(scores_file >> score >> window_size.x >> window_size.y && std::getline(scores_file, name))) {
break;
}
}
if (!name.empty()) {
name.erase(0, 1);
}
high_scores_[window_size].insert(HighScore(score, name, score_date));
}
if (!scores_file.eof())
throw std::runtime_error ("Error while reading high scores file '"+Config::Instance().GetScoreFileName()+"'!");
}
void HighScores::Save(std::ostream & scores_file) const
{
for (Ctn::const_iterator mapit (high_scores_.begin());
mapit != high_scores_.end(); ++mapit) {
for (std::multiset<HighScore>::const_iterator setit (mapit->second.begin());
setit != mapit->second.end(); ++setit) {
scores_file << 'T'
<< setit->Date() << ' '
<< setit->Value() << ' '
<< mapit->first.x << ' '
<< mapit->first.y << ' '
<< setit->Name() << '\n';
if (!scores_file.good()) {
throw std::runtime_error ("Error while saving high scores file '"+Config::Instance().GetScoreFileName()+"'!");
}
}
}
}
|