File: highscore.cc

package info (click to toggle)
xgalaga%2B%2B 0.8.4-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 336 kB
  • ctags: 557
  • sloc: cpp: 2,715; makefile: 128
file content (108 lines) | stat: -rw-r--r-- 2,834 bytes parent folder | download | duplicates (3)
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()+"'!");
			}
		}
	}
}