|
From: Lasse Kärkkäi. <tr...@us...> - 2009-11-14 18:43:39
|
Module: performous
Branch: dance
Commit: ef302080ba5424d521db1dc66d13e87b72a9e537
Author: Markus Raab <un...@ma...>
Date: Wed Nov 11 15:46:33 2009 +0100
Database now has the basic add* features
some style correction
check correct values in addHiscore
default track VOCALS
lookup() methods added
collate corrected
---
game/database.cc | 20 ++++++++++++++++++--
game/database.hh | 14 ++++++--------
game/hiscore.cc | 8 ++++++--
game/hiscore.hh | 2 +-
game/players.cc | 12 ++++++++++--
game/players.hh | 16 +++++++++++++++-
game/songitems.cc | 23 +++++++++++------------
game/songitems.hh | 20 +++++++++++++++++++-
8 files changed, 86 insertions(+), 29 deletions(-)
diff --git a/game/database.cc b/game/database.cc
index c71c21f..c8d67b6 100644
--- a/game/database.cc
+++ b/game/database.cc
@@ -61,12 +61,28 @@ std::string Database::file() {
return m_filename.string();
}
+void Database::addPlayer (std::string const& name, std::string const& picture, int id) {
+ m_players.addPlayer(name, picture, id);
+}
+
+void Database::addSong (boost::shared_ptr<Song> s) {
+ m_songs.addSong(s);
+}
+
+void Database::addHiscore (boost::shared_ptr<Song> s) {
+ int playerid = m_players.lookup(m_players.current().name);
+ int score = m_players.scores.front();
+ int songid = m_songs.lookup(s);
+ m_hiscores.addHiscore(score, playerid, songid);
+}
+
// Test program for Database
-int main()
-{
+int main() {
Database d("database.xml");
d.addPlayer("Markus", "m.jpg");
boost::shared_ptr<Song> s(new Song("/usr/share/songs/ABBA/ABBA - Dancing Queen/", "ABBA - Dancing Queen.txt"));
d.addSong(s);
+
+ d.addHiscore(s);
}
diff --git a/game/database.hh b/game/database.hh
index fd0f553..851e856 100644
--- a/game/database.hh
+++ b/game/database.hh
@@ -15,7 +15,7 @@
the program.*/
class Database
{
-public:
+ public:
Database (fs::path filename);
~Database ();
@@ -32,15 +32,13 @@ public:
std::string file();
-public: // methods for player management
+ public: // methods for player management
- void addPlayer (std::string const& name, std::string const& picture = "", int id = -1)
- { m_players.addPlayer(name, picture, id); }
+ void addPlayer (std::string const& name, std::string const& picture = "", int id = -1);
+ void addSong (boost::shared_ptr<Song> s);
+ void addHiscore (boost::shared_ptr<Song> s);
- void addSong (boost::shared_ptr<Song>s)
- { m_songs.addSong(s); }
-
-private:
+ private:
fs::path m_filename;
Players m_players;
diff --git a/game/hiscore.cc b/game/hiscore.cc
index 326e3c3..ff28b25 100644
--- a/game/hiscore.cc
+++ b/game/hiscore.cc
@@ -13,11 +13,17 @@ Hiscore::Hiscore()
void Hiscore::addHiscore(int score, int playerid, int songid, std::string const& track)
{
HiscoreItem hi;
+ if (score < 0) throw HiscoreException("Score negativ overflow");
+ if (score > 10000) throw HiscoreException("Score positive overflow");
hi.score = score;
+ if (playerid < 0) throw HiscoreException("No player given");
hi.playerid = playerid;
+
+ if (songid < 0) throw HiscoreException("No song given");
hi.songid = songid;
+ if (track.empty()) throw HiscoreException("No track given");
hi.track = track;
m_hiscore.insert(hi);
@@ -40,8 +46,6 @@ void Hiscore::load(xmlpp::NodeSet const& n)
xmlpp::TextNode* tn = element.get_child_text();
if (!tn) throw HiscoreException("Score not found");
int score = boost::lexical_cast<int>(tn->get_content());
- if (score < 0) throw HiscoreException("Score negativ overflow");
- if (score > 10000) throw HiscoreException("Score positive overflow");
std::string track;
if (!a_track) track = "VOCALS";
diff --git a/game/hiscore.hh b/game/hiscore.hh
index 88261c4..00f33c2 100644
--- a/game/hiscore.hh
+++ b/game/hiscore.hh
@@ -39,7 +39,7 @@ public:
void load(xmlpp::NodeSet const& n);
void save(xmlpp::Element *players);
- void addHiscore(int score, int playerid, int songid, std::string const& track);
+ void addHiscore(int score, int playerid, int songid, std::string const& track = "VOCALS");
private:
typedef std::multiset<HiscoreItem>hiscore_t;
diff --git a/game/players.cc b/game/players.cc
index c1d4b50..683a1e6 100644
--- a/game/players.cc
+++ b/game/players.cc
@@ -64,6 +64,15 @@ void Players::update() {
if (m_dirty) filter_internal();
}
+int Players::lookup(std::string const& name) {
+ for (players_t::const_iterator it = m_players.begin(); it != m_players.end(); ++it)
+ {
+ if (it->name == name) return it->id;
+ }
+
+ return -1;
+}
+
void Players::addPlayer (std::string const& name, std::string const& picture, int id) {
PlayerItem pi;
pi.id = id;
@@ -107,8 +116,7 @@ void Players::setFilter(std::string const& val) {
filter_internal();
}
-int Players::assign_id_internal()
-{
+int Players::assign_id_internal() {
players_t::const_reverse_iterator it = m_players.rbegin();
if (it != m_players.rend()) return it->id+1;
else return 1; // empty set
diff --git a/game/players.hh b/game/players.hh
index 51fc606..b035926 100644
--- a/game/players.hh
+++ b/game/players.hh
@@ -25,7 +25,19 @@ struct PlayersException: public std::runtime_error {
/**A collection of all Players.
The current players plugged in a song can
- be retrieved with Engine::getPlayers().*/
+ be retrieved with Engine::getPlayers().
+
+ There are 3 different views united in that collection.
+ There is a full players list which are used by the
+ database, but also for the filtering.
+
+ The filtered list is used to show players in
+ the screen_players.
+
+ The current lists (Players and scores) are used
+ to pass the information which players have won
+ to the ScoreScreen and then to the players window.
+ */
class Players: boost::noncopyable {
private:
typedef std::set<PlayerItem> players_t;
@@ -55,6 +67,8 @@ class Players: boost::noncopyable {
void update();
+ /// lookup a playerid using the players name
+ int lookup(std::string const& name);
/// add a player with a displayed name and an optional picture; if no id is given one will be assigned
void addPlayer (std::string const& name, std::string const& picture = "", int id = -1);
diff --git a/game/songitems.cc b/game/songitems.cc
index 4b1c522..99b4eba 100644
--- a/game/songitems.cc
+++ b/game/songitems.cc
@@ -10,8 +10,7 @@
#include <libxml++/libxml++.h>
-void SongItems::load(xmlpp::NodeSet const& n)
-{
+void SongItems::load(xmlpp::NodeSet const& n) {
for (xmlpp::NodeSet::const_iterator it = n.begin(); it != n.end(); ++it)
{
xmlpp::Element& element = dynamic_cast<xmlpp::Element&>(**it);
@@ -29,8 +28,7 @@ void SongItems::load(xmlpp::NodeSet const& n)
}
}
-void SongItems::save(xmlpp::Element *songs)
-{
+void SongItems::save(xmlpp::Element *songs) {
for (songs_t::const_iterator it = m_songs.begin(); it != m_songs.end(); ++it)
{
xmlpp::Element* song = songs->add_child("song");
@@ -40,8 +38,7 @@ void SongItems::save(xmlpp::Element *songs)
}
}
-void SongItems::addSongItem(std::string const& artist, std::string const& title, int id)
-{
+void SongItems::addSongItem(std::string const& artist, std::string const& title, int id) {
SongItem si;
if (id==-1) id = assign_id_internal();
si.id = id;
@@ -56,17 +53,19 @@ void SongItems::addSongItem(std::string const& artist, std::string const& title,
}
}
-void SongItems::addSong(boost::shared_ptr<Song> song)
-{
+void SongItems::addSong(boost::shared_ptr<Song> song) {
+ if (lookup(song) == -1) addSongItem(song->artist, song->title);
+}
+
+int SongItems::lookup(boost::shared_ptr<Song> song) {
for (songs_t::iterator it = m_songs.begin(); it != m_songs.end(); ++it)
{
- if (song->collateByArtistOnly == it->artist && song->collateByTitleOnly == it->title) return;
+ if (song->collateByArtistOnly == it->artist && song->collateByTitleOnly == it->title) return it->id;
}
- addSongItem(song->artist, song->title);
+ return -1;
}
-int SongItems::assign_id_internal()
-{
+int SongItems::assign_id_internal() {
songs_t::const_reverse_iterator it = m_songs.rbegin();
if (it != m_songs.rend()) return it->id+1;
else return 1; // empty set
diff --git a/game/songitems.hh b/game/songitems.hh
index d51c03d..9b1f2c5 100644
--- a/game/songitems.hh
+++ b/game/songitems.hh
@@ -32,6 +32,18 @@ struct SongItem
}
};
+/**A list of songs for the database.
+
+ Every song has a unique id managed by that database.
+ This class was introduced to hide the implementation
+ detail which data structure is used for the list away.
+
+ Currently a std::set is used, which makes both addSongItem()
+ and addSong() slow. The only advantage is that the id is
+ unique and it is cheap to get a new unique id.
+
+ When one of the methods is to slow, it can be optimized
+ easily. */
struct SongItems
{
void load(xmlpp::NodeSet const& n);
@@ -46,10 +58,16 @@ struct SongItems
/**Adds or Links an already existing song with an songitem.
The id will be assigned and artist and title will be filled in.
If there is already a song with the same artist and title nothing will be done.
+
+ lookup is used internally to achieve that.
*/
void addSong(boost::shared_ptr<Song> song);
-private:
+ /**Lookup a songid for a specific song.
+ @return -1 if no song found.*/
+ int lookup(boost::shared_ptr<Song> song);
+
+ private:
int assign_id_internal();
typedef std::set<SongItem> songs_t;
|