|
From: Markus R. <god...@us...> - 2009-11-12 12:49:42
|
Module: performous
Branch: master
Commit: 24c0972ea4ddc8a59a65a1a6d3680aafb051d236
Author: Markus Raab <un...@ma...>
Date: Wed Nov 11 11:58:37 2009 +0100
added songitems
---
game/database.cc | 6 +++++
game/database.hh | 4 ++-
game/players.hh | 3 +-
game/songitems.cc | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++
game/songitems.hh | 43 +++++++++++++++++++++++++++++++++++++
5 files changed, 115 insertions(+), 2 deletions(-)
diff --git a/game/database.cc b/game/database.cc
index 2a393ff..6190ffb 100644
--- a/game/database.cc
+++ b/game/database.cc
@@ -31,6 +31,9 @@ void Database::load() {
xmlpp::NodeSet hiscores = nodeRoot->find("/performous/hiscores/hiscore");
m_hiscores.load(hiscores);
+
+ xmlpp::NodeSet songs = nodeRoot->find("/performous/songs/song");
+ m_songs.load(songs);
}
void Database::save() {
@@ -43,6 +46,9 @@ void Database::save() {
xmlpp::Element *hiscores = nodeRoot->add_child("hiscores");
m_hiscores.save(hiscores);
+ xmlpp::Element *songs = nodeRoot->add_child("songs");
+ m_songs.save(songs);
+
if (!exists(m_filename.parent_path()) && !m_filename.parent_path().empty())
{
std::cout << "Will create directory: " << m_filename.parent_path() << std::endl;
diff --git a/game/database.hh b/game/database.hh
index 8ceb4d7..ba74745 100644
--- a/game/database.hh
+++ b/game/database.hh
@@ -4,6 +4,7 @@
#include "players.hh"
#include "hiscore.hh"
+#include "songitems.hh"
#include "fs.hh"
@@ -23,7 +24,7 @@ public:
@exception xmlpp exceptions may be thrown on any parse errors
@exception PlayersException if some conditions of players fail (e.g. no id)
@exception HiscoreException if some hiscore conditions fail (e.g. score too high)
- @exception SongsExceptions if some songs conditions fail (e.g. no id)
+ @exception SongItemsExceptions if some songs conditions fail (e.g. no id)
@post filled database
*/
void load();
@@ -41,4 +42,5 @@ private:
Players m_players;
Hiscore m_hiscores;
+ SongItems m_songs;
};
diff --git a/game/players.hh b/game/players.hh
index 17cc6d3..51fc606 100644
--- a/game/players.hh
+++ b/game/players.hh
@@ -4,12 +4,13 @@
#include <list>
#include <vector>
#include <string>
+#include <stdexcept>
#include <boost/noncopyable.hpp>
+#include "fs.hh"
#include "player.hh"
#include "animvalue.hh"
-#include "fs.hh"
namespace xmlpp { class Node; class Element; typedef std::vector<Node*>NodeSet; }
diff --git a/game/songitems.cc b/game/songitems.cc
new file mode 100644
index 0000000..775661c
--- /dev/null
+++ b/game/songitems.cc
@@ -0,0 +1,61 @@
+#include "songitems.hh"
+
+#include <string>
+
+#include <boost/lexical_cast.hpp>
+
+#include <libxml++/libxml++.h>
+
+
+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);
+
+ xmlpp::Attribute* a_id = element.get_attribute("id");
+ if (!a_id) throw SongItemsException("No attribute id");
+
+ xmlpp::Attribute* a_artist = element.get_attribute("artist");
+ if (!a_artist) throw SongItemsException("No attribute artist");
+
+ xmlpp::Attribute* a_title = element.get_attribute("title");
+ if (!a_title) throw SongItemsException("No attribute title");
+
+ addSong(a_artist->get_value(), a_title->get_value(), boost::lexical_cast<int>(a_id->get_value()));
+ }
+}
+
+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");
+ song->set_attribute("id", boost::lexical_cast<std::string>(it->id));
+ song->set_attribute("artist", it->artist);
+ song->set_attribute("title", it->title);
+ }
+}
+
+void SongItems::addSong(std::string const& artist, std::string const& title, int id)
+{
+ SongItem si;
+ if (id==-1) id = assign_id_internal();
+ si.id = id;
+ si.artist = artist;
+ si.title = title;
+
+ std::pair<songs_t::iterator, bool> ret = m_songs.insert(si);
+ if (!ret.second)
+ {
+ si.id = assign_id_internal();
+ m_songs.insert(si); // now do the insert with the fresh id
+ }
+}
+
+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
new file mode 100644
index 0000000..ee089b6
--- /dev/null
+++ b/game/songitems.hh
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <set>
+#include <vector>
+#include <string>
+#include <stdexcept>
+
+namespace xmlpp { class Node; class Element; typedef std::vector<Node*>NodeSet; }
+
+/**Exception which will be thrown when loading or
+ saving Players fails.*/
+struct SongItemsException: public std::runtime_error {
+ SongItemsException (std::string const& msg) :
+ runtime_error(msg)
+ {}
+};
+
+struct SongItem
+{
+ int id; // TODO use a PUID instead (LibOFA)
+
+ std::string artist;
+ std::string title;
+
+ bool operator< (SongItem const& other) const
+ {
+ return id < other.id;
+ }
+};
+
+struct SongItems
+{
+ void load(xmlpp::NodeSet const& n);
+ void save(xmlpp::Element *players);
+
+ void addSong(std::string const& artist, std::string const& title, int id = -1);
+
+private:
+ int assign_id_internal();
+
+ typedef std::set<SongItem> songs_t;
+ songs_t m_songs;
+};
|